[clang-tidy] Simplify modernize-use-default

Summary:
clang-tidy now cleans up after replacements, so leave colon and comma
removal to that.

Reviewers: angelgarcia, alexfh, aaron.ballman, djasper, ioeric

Subscribers: djasper, cfe-commits

Differential Revision: https://reviews.llvm.org/D25769

llvm-svn: 284735
This commit is contained in:
Malcolm Parsons 2016-10-20 15:31:34 +00:00
parent 3ad3f5033d
commit c2da631c5a
2 changed files with 20 additions and 51 deletions

View File

@ -20,37 +20,6 @@ namespace modernize {
static const char SpecialFunction[] = "SpecialFunction";
/// \brief Finds the SourceLocation of the colon ':' before the initialization
/// list in the definition of a constructor.
static SourceLocation getColonLoc(const ASTContext *Context,
const CXXConstructorDecl *Ctor) {
// FIXME: First init is the first initialization that is going to be
// performed, no matter what was the real order in the source code. If the
// order of the inits is wrong in the code, it may result in a false negative.
SourceLocation FirstInit = (*Ctor->init_begin())->getSourceLocation();
SourceLocation LastArg =
Ctor->getParamDecl(Ctor->getNumParams() - 1)->getLocEnd();
// We need to find the colon between the ')' and the first initializer.
bool Invalid = false;
StringRef Text = Lexer::getSourceText(
CharSourceRange::getCharRange(LastArg, FirstInit),
Context->getSourceManager(), Context->getLangOpts(), &Invalid);
if (Invalid)
return SourceLocation();
size_t ColonPos = Text.rfind(':');
if (ColonPos == StringRef::npos)
return SourceLocation();
Text = Text.drop_front(ColonPos + 1);
if (std::strspn(Text.data(), " \t\r\n") != Text.size()) {
// If there are comments, preprocessor directives or anything, abort.
return SourceLocation();
}
// FIXME: don't remove comments in the middle of the initializers.
return LastArg.getLocWithOffset(ColonPos);
}
/// \brief Finds all the named non-static fields of \p Record.
static std::set<const FieldDecl *>
getAllNamedFields(const CXXRecordDecl *Record) {
@ -262,7 +231,6 @@ void UseDefaultCheck::registerMatchers(MatchFinder *Finder) {
void UseDefaultCheck::check(const MatchFinder::MatchResult &Result) {
std::string SpecialFunctionName;
SourceLocation StartLoc, EndLoc;
// Both CXXConstructorDecl and CXXDestructorDecl inherit from CXXMethodDecl.
const auto *SpecialFunctionDecl =
@ -280,15 +248,13 @@ void UseDefaultCheck::check(const MatchFinder::MatchResult &Result) {
if (!Body)
return;
// Default locations.
StartLoc = Body->getLBracLoc();
EndLoc = Body->getRBracLoc();
// If there are comments inside the body, don't do the change.
if (!SpecialFunctionDecl->isCopyAssignmentOperator() &&
!bodyEmpty(Result.Context, Body))
return;
std::vector<FixItHint> RemoveInitializers;
if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(SpecialFunctionDecl)) {
if (Ctor->getNumParams() == 0) {
SpecialFunctionName = "default constructor";
@ -297,10 +263,9 @@ void UseDefaultCheck::check(const MatchFinder::MatchResult &Result) {
return;
SpecialFunctionName = "copy constructor";
// If there are constructor initializers, they must be removed.
if (Ctor->getNumCtorInitializers() != 0) {
StartLoc = getColonLoc(Result.Context, Ctor);
if (!StartLoc.isValid())
return;
for (const CXXCtorInitializer *Init : Ctor->inits()) {
RemoveInitializers.emplace_back(
FixItHint::CreateRemoval(Init->getSourceRange()));
}
}
} else if (isa<CXXDestructorDecl>(SpecialFunctionDecl)) {
@ -313,8 +278,8 @@ void UseDefaultCheck::check(const MatchFinder::MatchResult &Result) {
diag(SpecialFunctionDecl->getLocStart(),
"use '= default' to define a trivial " + SpecialFunctionName)
<< FixItHint::CreateReplacement(
CharSourceRange::getTokenRange(StartLoc, EndLoc), "= default;");
<< FixItHint::CreateReplacement(Body->getSourceRange(), "= default;")
<< RemoveInitializers;
}
} // namespace modernize

View File

@ -8,7 +8,7 @@ struct OL {
};
OL::OL(const OL &Other) : Field(Other.Field) {}
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a trivial copy constructor [modernize-use-default]
// CHECK-FIXES: OL::OL(const OL &Other) = default;
// CHECK-FIXES: OL::OL(const OL &Other) = default;
OL &OL::operator=(const OL &Other) {
Field = Other.Field;
return *this;
@ -20,7 +20,7 @@ OL &OL::operator=(const OL &Other) {
struct IL {
IL(const IL &Other) : Field(Other.Field) {}
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
// CHECK-FIXES: IL(const IL &Other) = default;
// CHECK-FIXES: IL(const IL &Other) = default;
IL &operator=(const IL &Other) {
Field = Other.Field;
return *this;
@ -43,7 +43,8 @@ struct Qual {
Mutable(Other.Mutable), Reference(Other.Reference),
Const(Other.Const) {}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use '= default'
// CHECK-FIXES: Qual(const Qual &Other) = default;
// CHECK-FIXES: Qual(const Qual &Other)
// CHECK-FIXES: = default;
int Field;
volatile char Volatile;
@ -80,6 +81,8 @@ MF &MF::operator=(const MF &Other) {
struct Comments {
Comments(const Comments &Other)
/* don't delete */ : /* this comment */ Field(Other.Field) {}
// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default'
// CHECK-FIXES: /* don't delete */ = default;
int Field;
};
@ -95,7 +98,7 @@ struct MoreComments {
struct ColonInComment {
ColonInComment(const ColonInComment &Other) /* : */ : Field(Other.Field) {}
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
// CHECK-FIXES: ColonInComment(const ColonInComment &Other) /* : */ = default;
// CHECK-FIXES: ColonInComment(const ColonInComment &Other) /* : */ = default;
int Field;
};
@ -116,7 +119,8 @@ struct BF {
BF(const BF &Other) : Field1(Other.Field1), Field2(Other.Field2), Field3(Other.Field3),
Field4(Other.Field4) {}
// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default'
// CHECK-FIXES: BF(const BF &Other) = default;
// CHECK-FIXES: BF(const BF &Other) {{$}}
// CHECK-FIXES: = default;
BF &operator=(const BF &);
unsigned Field1 : 3;
@ -140,7 +144,7 @@ BF &BF::operator=(const BF &Other) {
struct BC : IL, OL, BF {
BC(const BC &Other) : IL(Other), OL(Other), BF(Other) {}
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
// CHECK-FIXES: BC(const BC &Other) = default;
// CHECK-FIXES: BC(const BC &Other) = default;
BC &operator=(const BC &Other);
};
BC &BC::operator=(const BC &Other) {
@ -156,7 +160,7 @@ BC &BC::operator=(const BC &Other) {
struct BCWM : IL, OL {
BCWM(const BCWM &Other) : IL(Other), OL(Other), Bf(Other.Bf) {}
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
// CHECK-FIXES: BCWM(const BCWM &Other) = default;
// CHECK-FIXES: BCWM(const BCWM &Other) = default;
BCWM &operator=(const BCWM &);
BF Bf;
};
@ -200,7 +204,7 @@ struct VBC : VA, VB, virtual OL {
// is a virtual OL at the beginning of VA (which is the same).
VBC(const VBC &Other) : OL(Other), VA(Other), VB(Other) {}
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
// CHECK-FIXES: VBC(const VBC &Other) = default;
// CHECK-FIXES: VBC(const VBC &Other) = default;
VBC &operator=(const VBC &Other);
};
VBC &VBC::operator=(const VBC &Other) {
@ -335,7 +339,7 @@ CIB &CIB::operator=(const CIB &Other) {
struct NCRef {
NCRef(NCRef &Other) : Field1(Other.Field1), Field2(Other.Field2) {}
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
// CHECK-FIXES: NCRef(NCRef &Other) = default;
// CHECK-FIXES: NCRef(NCRef &Other) = default;
NCRef &operator=(NCRef &);
int Field1, Field2;
};