forked from OSchip/llvm-project
[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:
parent
3ad3f5033d
commit
c2da631c5a
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue