diff --git a/clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp b/clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp --- a/clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp @@ -36,6 +36,12 @@ "llvm-qualified-auto"); CheckFactories.registerCheck("llvm-twine-local"); } + + ClangTidyOptions getModuleOptions() override { + ClangTidyOptions Options; + Options.CheckOptions["llvm-qualified-auto.AddConstQualifier"] = "0"; + return Options; + } }; // Register the LLVMTidyModule using this statically initialized variable. diff --git a/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.h b/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.h --- a/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.h +++ b/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.h @@ -24,9 +24,14 @@ class QualifiedAutoCheck : public ClangTidyCheck { public: QualifiedAutoCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} + : ClangTidyCheck(Name, Context), + AddConstQualifier(Options.get("AddConstQualifier", true)) {} + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + +private: + const bool AddConstQualifier; }; } // namespace readability diff --git a/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.cpp b/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.cpp @@ -102,6 +102,10 @@ } // namespace +void QualifiedAutoCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "AddConstQualifier", AddConstQualifier); +} + void QualifiedAutoCheck::registerMatchers(MatchFinder *Finder) { if (!getLangOpts().CPlusPlus11) return; // Auto deduction not used in 'C or C++03 and earlier', so don't @@ -142,6 +146,8 @@ hasAnyTemplateArgument(IsBoundToType))))), "auto"), this); + if (!AddConstQualifier) + return; Finder->addMatcher(ExplicitSingleVarDecl( hasType(pointerType(pointee(autoType()))), "auto_ptr"), this); @@ -199,7 +205,8 @@ } std::string ReplStr = [&] { - llvm::StringRef PtrConst = isPointerConst(Var->getType()) ? "const " : ""; + llvm::StringRef PtrConst = + (AddConstQualifier && isPointerConst(Var->getType())) ? "const " : ""; llvm::StringRef LocalConst = IsLocalConst ? "const " : ""; llvm::StringRef LocalVol = IsLocalVolatile ? "volatile " : ""; llvm::StringRef LocalRestrict = IsLocalRestrict ? "__restrict " : ""; diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -104,6 +104,11 @@ Changes in existing checks ^^^^^^^^^^^^^^^^^^^^^^^^^^ +- Improved :doc:`readability-qualified-auto + ` check now supports a + `AddConstQualifier` to enable adding ``const`` qualifiers to auto typed + pointers and references. + - Improved :doc:`readability-redundant-string-init ` check now supports a `StringNames` option enabling its application to custom string classes. The diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability-qualified-auto.rst b/clang-tools-extra/docs/clang-tidy/checks/readability-qualified-auto.rst --- a/clang-tools-extra/docs/clang-tidy/checks/readability-qualified-auto.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability-qualified-auto.rst @@ -3,62 +3,72 @@ readability-qualified-auto ========================== -Adds pointer and ``const`` qualifications to ``auto``-typed variables that are deduced -to pointers and ``const`` pointers. +Adds pointer qualifications to ``auto``-typed variables that are deduced to +pointers. `LLVM Coding Standards `_ advises to -make it obvious if a ``auto`` typed variable is a pointer, constant pointer or -constant reference. This check will transform ``auto`` to ``auto *`` when the -type is deduced to be a pointer, as well as adding ``const`` when applicable to -``auto`` pointers or references +make it obvious if a ``auto`` typed variable is a pointer. This check will +transform ``auto`` to ``auto *`` when the type is deduced to be a pointer. .. code-block:: c++ - for (auto &Data : MutatableContainer) { - change(Data); - } - for (auto &Data : ConstantContainer) { - observe(Data); - } for (auto Data : MutatablePtrContainer) { change(*Data); } - for (auto Data : ConstantPtrContainer) { - observe(*Data); - } Would be transformed into: .. code-block:: c++ - for (auto &Data : MutatableContainer) { - change(Data); - } - for (const auto &Data : ConstantContainer) { - observe(Data); - } for (auto *Data : MutatablePtrContainer) { change(*Data); } - for (const auto *Data : ConstantPtrContainer) { - observe(*Data); - } Note const volatile qualified types will retain their const and volatile qualifiers. .. code-block:: c++ - const auto Foo = cast(Baz1); - const auto Bar = cast(Baz2); - volatile auto FooBar = cast(Baz3); + const auto Foo = cast(Baz1); + const auto Bar = cast(Baz2); + volatile auto FooBar = cast(Baz3); Would be transformed into: .. code-block:: c++ - auto *const Foo = cast(Baz1); - const auto *const Bar = cast(Baz2); - auto *volatile FooBar = cast(Baz3); + auto *const Foo = cast(Baz1); + auto *const Bar = cast(Baz2); + auto *volatile FooBar = cast(Baz3); + +Options +------- + +.. option:: AddConstQualifier + + When set to `1` the check will add const qualifiers to auto typed pointers + or references. + Default value is '1'. + +.. code-block:: c++ + + auto Foo1 = cast(Bar1); + auto &Foo2 = cast(Bar2); + + If AddConstQualifier is set to `0`, Will be transformed into: + +.. code-block:: c++ + + auto *Foo1 = cast(Bar1); + auto &Foo2 = cast(Bar2); + + Otherwise it will get be transformed into: + +.. code-block:: c++ + + const auto *Foo1 = cast(Bar1); + const auto &Foo2 = cast(Bar2); + + Note in the LLVM alias, the default value is `0`. This check helps to enforce this `LLVM Coding Standards recommendation `_. diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm-qualified-auto.cpp b/clang-tools-extra/test/clang-tidy/checkers/llvm-qualified-auto.cpp new file mode 100644 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/llvm-qualified-auto.cpp @@ -0,0 +1,21 @@ +// RUN: %check_clang_tidy %s llvm-qualified-auto %t + +// This check just ensures by default the llvm alias doesn't add const +// qualifiers to decls, so no need to copy the entire test file from +// readability-qualified-auto. + +int *getIntPtr(); +const int *getCIntPtr(); + +void foo() { + auto NakedPtr = getIntPtr(); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto NakedPtr' can be declared as 'auto *NakedPtr' + // CHECK-FIXES: {{^}} auto *NakedPtr = getIntPtr(); + auto NakedConstPtr = getCIntPtr(); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto NakedConstPtr' can be declared as 'auto *NakedConstPtr' + // CHECK-FIXES: {{^}} auto *NakedConstPtr = getCIntPtr(); + auto *Ptr = getIntPtr(); + auto *ConstPtr = getCIntPtr(); + auto &NakedRef = *getIntPtr(); + auto &NakedConstRef = *getCIntPtr(); +}