[PATCH] [clang-tidy] Detect dependent initializer_lists in google-explicit-constructor.
Alexander Kornienko
alexfh at google.com
Thu Feb 5 04:11:19 PST 2015
Hi djasper,
Detect constructors taking a single std::initializer_list even when it
is instantiation-dependent.
http://reviews.llvm.org/D7431
Files:
clang-tidy/google/ExplicitConstructorCheck.cpp
test/clang-tidy/google-explicit-constructor.cpp
Index: clang-tidy/google/ExplicitConstructorCheck.cpp
===================================================================
--- clang-tidy/google/ExplicitConstructorCheck.cpp
+++ clang-tidy/google/ExplicitConstructorCheck.cpp
@@ -49,14 +49,16 @@
}
bool isStdInitializerList(QualType Type) {
- if (const RecordType *RT = Type.getCanonicalType()->getAs<RecordType>()) {
- if (ClassTemplateSpecializationDecl *Specialization =
+ Type = Type.getCanonicalType();
+ if (const auto *TS = Type->getAs<TemplateSpecializationType>()) {
+ if (const TemplateDecl *TD = TS->getTemplateName().getAsTemplateDecl())
+ return TD->getName() == "initializer_list";
+ }
+ if (const auto *RT = Type->getAs<RecordType>()) {
+ if (auto *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";
+ return Template->getName() == "initializer_list";
}
}
return false;
Index: test/clang-tidy/google-explicit-constructor.cpp
===================================================================
--- test/clang-tidy/google-explicit-constructor.cpp
+++ test/clang-tidy/google-explicit-constructor.cpp
@@ -63,11 +63,11 @@
// 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 should not be declared explicit
// 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 should not be declared explicit
// CHECK-FIXES: {{^ }}B(::std::initializer_list<char> &&list6) {}
};
@@ -79,13 +79,35 @@
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 should not be declared explicit
+ // 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) {}
+};
+
struct D {
template <typename T>
explicit D(T t) {}
};
template <typename T>
struct E {
+ E(T *pt) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors must be explicit
+ // CHECK-FIXES: {{^ }}explicit E(T *pt) {}
+
explicit E(T t) {}
template <typename U>
explicit E(U u) {}
@@ -96,3 +118,4 @@
E<decltype(list)> e(list);
E<int> e2(list);
}
+
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D7431.19395.patch
Type: text/x-patch
Size: 3378 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150205/d6ecbd12/attachment.bin>
More information about the cfe-commits
mailing list