[clang-tools-extra] r228289 - [clang-tidy] Detect dependent initializer_lists in google-explicit-constructor.

Alexander Kornienko alexfh at google.com
Thu Feb 5 04:49:08 PST 2015


Author: alexfh
Date: Thu Feb  5 06:49:07 2015
New Revision: 228289

URL: http://llvm.org/viewvc/llvm-project?rev=228289&view=rev
Log:
[clang-tidy] Detect dependent initializer_lists in google-explicit-constructor.

Summary:
Detect constructors taking a single std::initializer_list even when it
is instantiation-dependent.

Reviewers: djasper

Reviewed By: djasper

Subscribers: curdeius, cfe-commits

Differential Revision: http://reviews.llvm.org/D7431

Modified:
    clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp
    clang-tools-extra/trunk/test/clang-tidy/google-explicit-constructor.cpp

Modified: clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp?rev=228289&r1=228288&r2=228289&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp Thu Feb  5 06:49:07 2015
@@ -48,16 +48,23 @@ SourceRange FindToken(const SourceManage
   return SourceRange();
 }
 
+bool declIsStdInitializerList(const NamedDecl *D) {
+  // First use the fast getName() method to avoid unnecessary calls to the
+  // slow getQualifiedNameAsString().
+  return D->getName() == "initializer_list" &&
+         D->getQualifiedNameAsString() == "std::initializer_list";
+}
+
 bool isStdInitializerList(QualType Type) {
-  if (const RecordType *RT = Type.getCanonicalType()->getAs<RecordType>()) {
-    if (ClassTemplateSpecializationDecl *Specialization =
-            dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl())) {
-      ClassTemplateDecl *Template = Specialization->getSpecializedTemplate();
-      // First use the fast getName() method to avoid unnecessary calls to the
-      // slow getQualifiedNameAsString().
-      return Template->getName() == "initializer_list" &&
-             Template->getQualifiedNameAsString() == "std::initializer_list";
-    }
+  Type = Type.getCanonicalType();
+  if (const auto *TS = Type->getAs<TemplateSpecializationType>()) {
+    if (const TemplateDecl *TD = TS->getTemplateName().getAsTemplateDecl())
+      return declIsStdInitializerList(TD);
+  }
+  if (const auto *RT = Type->getAs<RecordType>()) {
+    if (const auto *Specialization =
+            dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl()))
+      return declIsStdInitializerList(Specialization->getSpecializedTemplate());
   }
   return false;
 }

Modified: clang-tools-extra/trunk/test/clang-tidy/google-explicit-constructor.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/google-explicit-constructor.cpp?rev=228289&r1=228288&r2=228289&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/google-explicit-constructor.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/google-explicit-constructor.cpp Thu Feb  5 06:49:07 2015
@@ -49,7 +49,7 @@ struct A {
   // CHECK-FIXES: {{^  }}explicit A(int x1) {}
 
   A(double x2, double y = 3.14) {}
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors must be explicit
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors
   // CHECK-FIXES: {{^  }}explicit A(double x2, double y = 3.14) {}
 };
 
@@ -63,11 +63,11 @@ struct B {
   // CHECK-FIXES: {{^  }}B(::std::initializer_list<double> list4) {}
 
   explicit B(const ::std::initializer_list<char> &list5) {}
-  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor should not be declared explicit [google-explicit-constructor]
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor
   // CHECK-FIXES: {{^  }}B(const ::std::initializer_list<char> &list5) {}
 
   explicit B(::std::initializer_list<char> &&list6) {}
-  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor should not be declared explicit [google-explicit-constructor]
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor
   // CHECK-FIXES: {{^  }}B(::std::initializer_list<char> &&list6) {}
 };
 
@@ -79,6 +79,27 @@ struct C {
   C(initializer_list<unsigned> &&list3) {}
 };
 
+template <typename T>
+struct C2 {
+  C2(initializer_list<int> list1) {}
+  C2(const initializer_list<unsigned> &list2) {}
+  C2(initializer_list<unsigned> &&list3) {}
+
+  explicit C2(initializer_list<double> list4) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor
+  // CHECK-FIXES: {{^  }}C2(initializer_list<double> list4) {}
+};
+
+template <typename T>
+struct C3 {
+  C3(initializer_list<T> list1) {}
+  C3(const std::initializer_list<T*> &list2) {}
+  C3(::std::initializer_list<T**> &&list3) {}
+
+  template <typename U>
+  C3(initializer_list<U> list3) {}
+};
+
 struct D {
   template <typename T>
   explicit D(T t) {}
@@ -86,6 +107,14 @@ struct D {
 
 template <typename T>
 struct E {
+  E(T *pt) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors
+  // CHECK-FIXES: {{^  }}explicit E(T *pt) {}
+  template <typename U>
+  E(U *pu) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors
+  // CHECK-FIXES: {{^  }}explicit E(U *pu) {}
+
   explicit E(T t) {}
   template <typename U>
   explicit E(U u) {}





More information about the cfe-commits mailing list