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) {} _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
