Fix ExplicitConstructorCheck to warn only on in-class declarations.
authorAlexander Kornienko <alexfh@google.com>
Thu, 13 Feb 2014 10:11:48 +0000 (10:11 +0000)
committerAlexander Kornienko <alexfh@google.com>
Thu, 13 Feb 2014 10:11:48 +0000 (10:11 +0000)
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

clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp
clang-tools-extra/unittests/clang-tidy/GoogleModuleTest.cpp

index 8b25d02..2562893 100644 (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 {
index 4d34043..48433f4 100644 (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