forked from OSchip/llvm-project
[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 llvm-svn: 228289
This commit is contained in:
parent
30029c6b58
commit
dd2dad0d24
|
@ -48,16 +48,23 @@ SourceRange FindToken(const SourceManager &Sources, LangOptions LangOpts,
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -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) {}
|
||||
|
|
Loading…
Reference in New Issue