This revision was automatically updated to reflect the committed changes. Closed by commit rCTE334829: [clang-tidy] This patch is a fix for D45405 where spaces were mistakenly… (authored by zinovy.nis, committed by ).
Changed prior to commit: https://reviews.llvm.org/D45927?vs=146677&id=151500#toc Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D45927 Files: clang-tidy/modernize/UseAutoCheck.cpp docs/clang-tidy/checks/modernize-use-auto.rst test/clang-tidy/modernize-use-auto-min-type-name-length.cpp
Index: test/clang-tidy/modernize-use-auto-min-type-name-length.cpp =================================================================== --- test/clang-tidy/modernize-use-auto-min-type-name-length.cpp +++ test/clang-tidy/modernize-use-auto-min-type-name-length.cpp @@ -1,30 +1,85 @@ -// RUN: %check_clang_tidy %s modernize-use-auto %t -- \ -// RUN: -config="{CheckOptions: [{key: modernize-use-auto.MinTypeNameLength, value: '5'}]}" \ -// RUN: -- -std=c++11 -frtti - -extern int foo(); - -using VeryVeryVeryLongTypeName = int; +// RUN: %check_clang_tidy -check-suffix=0-0 %s modernize-use-auto %t -- -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: 0}, {key: modernize-use-auto.MinTypeNameLength, value: 0}]}" -- --std=c++11 -frtti +// RUN: %check_clang_tidy -check-suffix=0-8 %s modernize-use-auto %t -- -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: 0}, {key: modernize-use-auto.MinTypeNameLength, value: 8}]}" -- --std=c++11 -frtti +// RUN: %check_clang_tidy -check-suffix=1-0 %s modernize-use-auto %t -- -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: 1}, {key: modernize-use-auto.MinTypeNameLength, value: 0}]}" -- --std=c++11 -frtti +// RUN: %check_clang_tidy -check-suffix=1-8 %s modernize-use-auto %t -- -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: 1}, {key: modernize-use-auto.MinTypeNameLength, value: 8}]}" -- --std=c++11 -frtti + +template <class T> extern T foo(); +template <class T> struct P { explicit P(T t) : t_(t) {} T t_;}; +template <class T> P<T> *foo_ptr(); +template <class T> P<T> &foo_ref(); int bar() { - int a = static_cast<VeryVeryVeryLongTypeName>(foo()); - // strlen('int') = 4 < 5, so skip it, - // even strlen('VeryVeryVeryLongTypeName') > 5. - - unsigned b = static_cast<unsigned>(foo()); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto] - // CHECK-FIXES: auto b = static_cast<unsigned>(foo()); - - bool c = static_cast<bool>(foo()); - // strlen('bool') = 4 < 5, so skip it. - - const bool c1 = static_cast<const bool>(foo()); - // strlen('bool') = 4 < 5, so skip it, even there's a 'const'. - - unsigned long long ull = static_cast<unsigned long long>(foo()); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto] - // CHECK-FIXES: auto ull = static_cast<unsigned long long>(foo()); + { + // Lenth(long) = 4 + long i = static_cast<long>(foo<long>()); + // CHECK-FIXES-0-0: auto i = {{.*}} + // CHECK-FIXES-0-8: long i = {{.*}} + // CHECK-FIXES-1-0: auto i = {{.*}} + // CHECK-FIXES-1-8: long i = {{.*}} + const long ci = static_cast<long>(foo<const long>()); + // CHECK-FIXES-0-0: auto ci = {{.*}} + // CHECK-FIXES-0-8: long ci = {{.*}} + // CHECK-FIXES-1-0: auto ci = {{.*}} + // CHECK-FIXES-1-8: long ci = {{.*}} + long *pi = static_cast<long *>(foo<long *>()); + // CHECK-FIXES-0-0: auto *pi = {{.*}} + // CHECK-FIXES-0-8: long *pi = {{.*}} + // CHECK-FIXES-1-0: auto pi = {{.*}} + // CHECK-FIXES-1-8: long *pi = {{.*}} + + // Length(long *) is still 5 + long * pi2 = static_cast<long *>(foo<long *>()); + // CHECK-FIXES-0-0: auto * pi2 = {{.*}} + // CHECK-FIXES-0-8: long * pi2 = {{.*}} + // CHECK-FIXES-1-0: auto pi2 = {{.*}} + // CHECK-FIXES-1-8: long * pi2 = {{.*}} + + // Length(long **) = 6 + long **ppi = static_cast<long **>(foo<long **>()); + // CHECK-FIXES-0-0: auto **ppi = {{.*}} + // CHECK-FIXES-0-8: long **ppi = {{.*}} + // CHECK-FIXES-1-0: auto ppi = {{.*}} + // CHECK-FIXES-1-8: long **ppi = {{.*}} + } + + { + // Lenth(long int) = 4 + 1 + 3 = 8 + // Lenth(long int) is still 8 + long int i = static_cast<long int>(foo<long int>()); + // CHECK-FIXES-0-0: auto i = {{.*}} + // CHECK-FIXES-0-8: auto i = {{.*}} + // CHECK-FIXES-1-0: auto i = {{.*}} + // CHECK-FIXES-1-8: auto i = {{.*}} + + long int *pi = static_cast<long int *>(foo<long int *>()); + // CHECK-FIXES-0-0: auto *pi = {{.*}} + // CHECK-FIXES-0-8: auto *pi = {{.*}} + // CHECK-FIXES-1-0: auto pi = {{.*}} + // CHECK-FIXES-1-8: auto pi = {{.*}} + } + + // Templates + { + // Length(P<long>) = 7 + P<long>& i = static_cast<P<long>&>(foo_ref<long>()); + // CHECK-FIXES-0-0: auto& i = {{.*}} + // CHECK-FIXES-0-8: P<long>& i = {{.*}} + // CHECK-FIXES-1-0: auto & i = {{.*}} + // CHECK-FIXES-1-8: P<long>& i = {{.*}} + + // Length(P<long*>) = 8 + P<long*>& pi = static_cast<P<long*> &>(foo_ref<long*>()); + // CHECK-FIXES-0-0: auto& pi = {{.*}} + // CHECK-FIXES-0-8: auto& pi = {{.*}} + // CHECK-FIXES-1-0: auto & pi = {{.*}} + // CHECK-FIXES-1-8: auto & pi = {{.*}} + + P<long>* pi2 = static_cast<P<long>*>(foo_ptr<long>()); + // CHECK-FIXES-0-0: auto* pi2 = {{.*}} + // CHECK-FIXES-0-8: P<long>* pi2 = {{.*}} + // CHECK-FIXES-1-0: auto pi2 = {{.*}} + // CHECK-FIXES-1-8: auto pi2 = {{.*}} + } return 1; } - Index: clang-tidy/modernize/UseAutoCheck.cpp =================================================================== --- clang-tidy/modernize/UseAutoCheck.cpp +++ clang-tidy/modernize/UseAutoCheck.cpp @@ -11,6 +11,7 @@ #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Basic/CharInfo.h" #include "clang/Tooling/FixIt.h" using namespace clang; @@ -27,6 +28,34 @@ const char DeclWithCastId[] = "decl_cast"; const char DeclWithTemplateCastId[] = "decl_template"; +size_t GetTypeNameLength(bool RemoveStars, StringRef Text) { + enum CharType { Space, Alpha, Punctuation }; + CharType LastChar = Space, BeforeSpace = Punctuation; + size_t NumChars = 0; + int TemplateTypenameCntr = 0; + for (const unsigned char C : Text) { + if (C == '<') + ++TemplateTypenameCntr; + else if (C == '>') + --TemplateTypenameCntr; + const CharType NextChar = + isAlphanumeric(C) + ? Alpha + : (isWhitespace(C) || + (!RemoveStars && TemplateTypenameCntr == 0 && C == '*')) + ? Space + : Punctuation; + if (NextChar != Space) { + ++NumChars; // Count the non-space character. + if (LastChar == Space && NextChar == Alpha && BeforeSpace == Alpha) + ++NumChars; // Count a single space character between two words. + BeforeSpace = NextChar; + } + LastChar = NextChar; + } + return NumChars; +} + /// \brief Matches variable declarations that have explicit initializers that /// are not initializer lists. /// @@ -419,8 +448,10 @@ SourceRange Range(Loc.getSourceRange()); if (MinTypeNameLength != 0 && - tooling::fixit::getText(Loc.getSourceRange(), FirstDecl->getASTContext()) - .size() < MinTypeNameLength) + GetTypeNameLength(RemoveStars, + tooling::fixit::getText(Loc.getSourceRange(), + FirstDecl->getASTContext())) < + MinTypeNameLength) return; auto Diag = diag(Range.getBegin(), Message); Index: docs/clang-tidy/checks/modernize-use-auto.rst =================================================================== --- docs/clang-tidy/checks/modernize-use-auto.rst +++ docs/clang-tidy/checks/modernize-use-auto.rst @@ -182,20 +182,37 @@ If the option is set to non-zero (default `5`), the check will ignore type names having a length less than the option value. The option affects expressions only, not iterators. + Spaces between multi-lexeme type names (``long int``) are considered as one. + If ``RemoveStars`` option (see below) is set to non-zero, then ``*s`` in + the type are also counted as a part of the type name. .. code-block:: c++ - // MinTypeNameLength = 0 + // MinTypeNameLength = 0, RemoveStars=0 int a = static_cast<int>(foo()); // ---> auto a = ... - bool b = new bool; // ---> auto b = ... + // length(bool *) = 4 + bool *b = new bool; // ---> auto *b = ... unsigned c = static_cast<unsigned>(foo()); // ---> auto c = ... - // MinTypeNameLength = 8 + // MinTypeNameLength = 5, RemoveStars=0 - int a = static_cast<int>(foo()); // ---> int a = ... - bool b = new bool; // ---> bool b = ... - unsigned c = static_cast<unsigned>(foo()); // ---> auto c = ... + int a = static_cast<int>(foo()); // ---> int a = ... + bool b = static_cast<bool>(foo()); // ---> bool b = ... + bool *pb = static_cast<bool*>(foo()); // ---> bool *pb = ... + unsigned c = static_cast<unsigned>(foo()); // ---> auto c = ... + // length(long <on-or-more-spaces> int) = 8 + long int d = static_cast<long int>(foo()); // ---> auto d = ... + + // MinTypeNameLength = 5, RemoveStars=1 + + int a = static_cast<int>(foo()); // ---> int a = ... + // length(int * * ) = 5 + int **pa = static_cast<int**>(foo()); // ---> auto pa = ... + bool b = static_cast<bool>(foo()); // ---> bool b = ... + bool *pb = static_cast<bool*>(foo()); // ---> auto pb = ... + unsigned c = static_cast<unsigned>(foo()); // ---> auto c = ... + long int d = static_cast<long int>(foo()); // ---> auto d = ... .. option:: RemoveStars
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits