Index: clang-tidy/modernize/UseAutoCheck.h =================================================================== --- clang-tidy/modernize/UseAutoCheck.h +++ clang-tidy/modernize/UseAutoCheck.h @@ -29,6 +29,7 @@ llvm::function_ref GetType, StringRef Message); + const unsigned int MinTypeNameLength; const bool RemoveStars; }; 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/Tooling/FixIt.h" using namespace clang; using namespace clang::ast_matchers; @@ -286,10 +287,11 @@ } // namespace UseAutoCheck::UseAutoCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context), - RemoveStars(Options.get("RemoveStars", 0)) {} + : ClangTidyCheck(Name, Context), RemoveStars(Options.get("RemoveStars", 0)), + MinTypeNameLength(Options.get("MinTypeNameLength", 5)) {} void UseAutoCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "MinTypeNameLength", MinTypeNameLength); Options.store(Opts, "RemoveStars", RemoveStars ? 1 : 0); } @@ -414,6 +416,12 @@ Loc = Loc.getNextTypeLoc(); } SourceRange Range(Loc.getSourceRange()); + + if (MinTypeNameLength != 0 && + tooling::fixit::getText(Loc.getSourceRange(), FirstDecl->getASTContext()) + .size() < MinTypeNameLength) + return; + auto Diag = diag(Range.getBegin(), Message); // Space after 'auto' to handle cases where the '*' in the pointer type is Index: docs/ReleaseNotes.rst =================================================================== --- docs/ReleaseNotes.rst +++ docs/ReleaseNotes.rst @@ -57,6 +57,11 @@ Improvements to clang-tidy -------------------------- +- New option `MinTypeNameLength` for `modernize-use-auto` to limit the minimal + length of type names to be replaced with 'auto'. Use to skip replacing + short type names like 'int'/'bool' -> 'auto'. Default value is 5 which means + replace types with the name length >= 5 letters only (ex. double, unsigned). + - New module `abseil` for checks related to the `Abseil `_ library. 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 @@ -194,3 +194,23 @@ // RemoveStars = 1 auto my_first_pointer = new TypeName, my_second_pointer = new TypeName; + +.. option:: MinTypeNameLength + + 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. + +.. code-block:: c++ + + // MinTypeNameLength = 0 + + int a = static_cast(foo()); // ---> auto a = ... + bool b = new bool; // ---> auto b = ... + unsigned c = static_cast(foo()); // ---> auto c = ... + + // MinTypeNameLength = 8 + + int a = static_cast(foo()); // ---> int a = ... + bool b = new bool; // ---> bool b = ... + unsigned c = static_cast(foo()); // ---> auto c = ... Index: test/clang-tidy/modernize-use-auto-cast-remove-stars.cpp =================================================================== --- test/clang-tidy/modernize-use-auto-cast-remove-stars.cpp +++ test/clang-tidy/modernize-use-auto-cast-remove-stars.cpp @@ -1,5 +1,5 @@ // RUN: %check_clang_tidy %s modernize-use-auto %t -- \ -// RUN: -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: '1'}]}" \ +// RUN: -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: '1'} , {key: modernize-use-auto.MinTypeNameLength, value: '0'}]}" \ // RUN: -- -std=c++11 -frtti struct A { Index: test/clang-tidy/modernize-use-auto-cast.cpp =================================================================== --- test/clang-tidy/modernize-use-auto-cast.cpp +++ test/clang-tidy/modernize-use-auto-cast.cpp @@ -1,5 +1,6 @@ -// RUN: %check_clang_tidy %s modernize-use-auto %t -- -- \ -// RUN: -std=c++11 -I %S/Inputs/modernize-use-auto -frtti +// RUN: %check_clang_tidy %s modernize-use-auto %t -- \ +// RUN: -config="{CheckOptions: [{key: modernize-use-auto.MinTypeNameLength, value: '0'}]}" \ +// RUN: -- -std=c++11 -I %S/Inputs/modernize-use-auto -frtti struct A { virtual ~A() {} Index: test/clang-tidy/modernize-use-auto-min-type-name-length.cpp =================================================================== --- /dev/null +++ test/clang-tidy/modernize-use-auto-min-type-name-length.cpp @@ -0,0 +1,30 @@ +// 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; + +int bar() { + int a = static_cast(foo()); + // strlen('int') = 4 < 5, so skip it, + // even strlen('VeryVeryVeryLongTypeName') > 5. + + unsigned b = static_cast(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(foo()); + + bool c = static_cast(foo()); + // strlen('bool') = 4 < 5, so skip it. + + const bool c1 = static_cast(foo()); + // strlen('bool') = 4 < 5, so skip it, even there's a 'const'. + + unsigned long long ull = static_cast(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(foo()); + + return 1; +} + Index: test/clang-tidy/modernize-use-auto-new.cpp =================================================================== --- test/clang-tidy/modernize-use-auto-new.cpp +++ test/clang-tidy/modernize-use-auto-new.cpp @@ -1,4 +1,6 @@ -// RUN: %check_clang_tidy %s modernize-use-auto %t +// RUN: %check_clang_tidy %s modernize-use-auto %t -- \ +// RUN: -config="{CheckOptions: [{key: modernize-use-auto.MinTypeNameLength, value: '0'}]}" \ +// RUN: -- -std=c++11 -frtti class MyType {};