Fix ExplicitConstructorCheck to warn only on in-class declarations.

Summary:
I'm not absolutely sure this is 100% correct solution, but it seems to
do what I expect.

Reviewers: djasper, klimek

Reviewed By: djasper

CC: cfe-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D2756

llvm-svn: 201308
This commit is contained in:
Alexander Kornienko 2014-02-13 10:11:48 +00:00
parent c4b4924a13
commit 32eaa37b15
2 changed files with 17 additions and 10 deletions

View File

@ -24,20 +24,22 @@ using namespace clang::ast_matchers;
namespace clang {
namespace tidy {
void
ExplicitConstructorCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
Finder->addMatcher(constructorDecl().bind("construct"), this);
void ExplicitConstructorCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(constructorDecl().bind("ctor"), this);
}
void ExplicitConstructorCheck::check(const MatchFinder::MatchResult &Result) {
const CXXConstructorDecl *Ctor =
Result.Nodes.getNodeAs<CXXConstructorDecl>("construct");
if (!Ctor->isExplicit() && !Ctor->isImplicit() && Ctor->getNumParams() >= 1 &&
Ctor->getMinRequiredArguments() <= 1) {
SourceLocation Loc = Ctor->getLocation();
diag(Loc, "Single-argument constructors must be explicit")
<< FixItHint::CreateInsertion(Loc, "explicit ");
}
Result.Nodes.getNodeAs<CXXConstructorDecl>("ctor");
// Do not be confused: isExplicit means 'explicit' keyword is present,
// isImplicit means that it's a compiler-generated constructor.
if (Ctor->isOutOfLine() || Ctor->isExplicit() || Ctor->isImplicit())
return;
if (Ctor->getNumParams() == 0 || Ctor->getMinRequiredArguments() > 1)
return;
SourceLocation Loc = Ctor->getLocation();
diag(Loc, "Single-argument constructors must be explicit")
<< FixItHint::CreateInsertion(Loc, "explicit ");
}
class GoogleModule : public ClangTidyModule {

View File

@ -21,5 +21,10 @@ TEST_F(ExplicitConstructorCheckTest, DefaultParameters) {
runCheckOn("class C { C(int i, int j = 0); };"));
}
TEST_F(ExplicitConstructorCheckTest, OutOfLineDefinitions) {
EXPECT_EQ("class C { explicit C(int i); }; C::C(int i) {}",
runCheckOn("class C { C(int i); }; C::C(int i) {}"));
}
} // namespace tidy
} // namespace clang