[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