[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
https://github.com/denzor200 requested changes to this pull request. https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
@@ -0,0 +1,76 @@ +// RUN: %check_clang_tidy -std=c++17 %s modernize-make-direct %t + +namespace std { +template +struct optional { + optional(const T&) {} +}; + +template +optional make_optional(const T& t) { return optional(t); } + +template +struct unique_ptr { + explicit unique_ptr(T*) {} +}; + +template +unique_ptr make_unique(Args&&... args) { + return unique_ptr(new T(args...)); +} + +template +struct shared_ptr { + shared_ptr(T*) {} +}; + +template +shared_ptr make_shared(Args&&... args) { + return shared_ptr(new T(args...)); +} + +template +struct pair { + T first; + U second; + pair(const T& x, const U& y) : first(x), second(y) {} +}; + +template +pair make_pair(T&& t, U&& u) { + return pair(t, u); +} + +template +struct tuple { + tuple(const T&... args) {} +}; + +template +tuple make_tuple(T&&... t) { + return tuple(t...); +} +} + +struct Widget { + Widget(int x) {} +}; + + +void basic_tests() { + auto o1 = std::make_optional(42); + // CHECK-MESSAGES: warning: use class template argument deduction (CTAD) instead of std::make_optional [modernize-make-direct] + // CHECK-FIXES: auto o1 = std::optional(42); + + // make_unique and make_shared are not transformed by this check + auto u1 = std::make_unique(1); + auto s1 = std::make_shared(2); + + auto p1 = std::make_pair(1, "test"); + // CHECK-MESSAGES: warning: use class template argument deduction (CTAD) instead of std::make_pair [modernize-make-direct] + // CHECK-FIXES: auto p1 = std::pair(1, "test"); + + auto t1 = std::make_tuple(1, 2.0, "hi"); denzor200 wrote: please add ``` const int arg = 2.0; auto t2 = std::make_tuple(1, std::cref(arg), "hi"); ``` this check must be silent in this case https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
@@ -0,0 +1,78 @@ +//===--- MakeFunctionToDirectCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MakeFunctionToDirectCheck.h" +#include "../utils/TransformerClangTidyCheck.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Tooling/Transformer/RangeSelector.h" +#include "clang/Tooling/Transformer/RewriteRule.h" +#include "clang/Tooling/Transformer/Stencil.h" + +using namespace ::clang::ast_matchers; +using namespace ::clang::transformer; + +namespace clang::tidy::modernize { + +namespace { + +RewriteRuleWith +makeFunctionToDirectCheckImpl(bool CheckMakePair, bool CheckMakeOptional, + bool CheckMakeTuple) { + std::vector> Rules; + + // Helper to create a rule for a specific make_* function + auto createRule = [](StringRef MakeFunction, StringRef DirectType) { +auto WarningMessage = cat("use class template argument deduction (CTAD) " + "instead of ", + MakeFunction); + +return makeRule( +callExpr(callee(functionDecl(hasName(MakeFunction))), + unless(hasParent(implicitCastExpr(hasImplicitDestinationType( + qualType(hasCanonicalType(qualType(asString("void") +.bind("make_call"), +changeTo(node("make_call"), + cat(DirectType, "(", callArgs("make_call"), ")")), +WarningMessage); + }; + + if (CheckMakeOptional) { +Rules.push_back(createRule("std::make_optional", "std::optional")); + } + + if (CheckMakePair) { +Rules.push_back(createRule("std::make_pair", "std::pair")); + } + + if (CheckMakeTuple) { +Rules.push_back(createRule("std::make_tuple", "std::tuple")); + } + + return applyFirst(Rules); +} + +} // namespace + +MakeFunctionToDirectCheck::MakeFunctionToDirectCheck(StringRef Name, + ClangTidyContext *Context) +: utils::TransformerClangTidyCheck(Name, Context), + CheckMakePair(Options.get("CheckMakePair", true)), + CheckMakeOptional(Options.get("CheckMakeOptional", true)), + CheckMakeTuple(Options.get("CheckMakeTuple", true)) { + setRule(makeFunctionToDirectCheckImpl(CheckMakePair, CheckMakeOptional, +CheckMakeTuple)); +} + +void MakeFunctionToDirectCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "CheckMakePair", CheckMakePair); + Options.store(Opts, "CheckMakeOptional", CheckMakeOptional); + Options.store(Opts, "CheckMakeTuple", CheckMakeTuple); +} + +} // namespace clang::tidy::modernize vbvictor wrote: Add newline https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
@@ -124,6 +124,12 @@ New checks pointer and store it as class members without handle the copy and move constructors and the assignments. +- New :doc:`modernize-make-direct ` check. vbvictor wrote: Please format alphabetically and place doc string same as other checks. `<>` should be on the next line https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
@@ -0,0 +1,78 @@ +//===--- MakeFunctionToDirectCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MakeFunctionToDirectCheck.h" +#include "../utils/TransformerClangTidyCheck.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Tooling/Transformer/RangeSelector.h" +#include "clang/Tooling/Transformer/RewriteRule.h" +#include "clang/Tooling/Transformer/Stencil.h" + +using namespace ::clang::ast_matchers; +using namespace ::clang::transformer; + +namespace clang::tidy::modernize { + +namespace { + +RewriteRuleWith +makeFunctionToDirectCheckImpl(bool CheckMakePair, bool CheckMakeOptional, + bool CheckMakeTuple) { + std::vector> Rules; + + // Helper to create a rule for a specific make_* function + auto createRule = [](StringRef MakeFunction, StringRef DirectType) { +auto WarningMessage = cat("use class template argument deduction (CTAD) " + "instead of ", + MakeFunction); + +return makeRule( +callExpr(callee(functionDecl(hasName(MakeFunction))), + unless(hasParent(implicitCastExpr(hasImplicitDestinationType( + qualType(hasCanonicalType(qualType(asString("void") vbvictor wrote: Could you please elaborate why do you need this `unless(hasParen(...))` in your check? I didn't find tests that will use this behavior, or I couldn't understand what existing test used it:( https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
@@ -0,0 +1,39 @@ +//===--- MakeFunctionToDirectCheck.h - clang-tidy --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKEFUNCTIONTODIRECTCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKEFUNCTIONTODIRECTCHECK_H + +#include "../utils/TransformerClangTidyCheck.h" + +namespace clang::tidy::modernize { + +/// Converts std::make_* function calls to direct constructor calls using +/// class template argument deduction (CTAD). +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/modernize/make-direct.html +class MakeFunctionToDirectCheck : public utils::TransformerClangTidyCheck { +public: + MakeFunctionToDirectCheck(StringRef Name, ClangTidyContext *Context); + + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { +return LangOpts.CPlusPlus17; + } + + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + +private: + const bool CheckMakePair; + const bool CheckMakeOptional; + const bool CheckMakeTuple; +}; + +} // namespace clang::tidy::modernize + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKEFUNCTIONTODIRECTCHECK_H vbvictor wrote: Add newline https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
llvmbot wrote: @llvm/pr-subscribers-clang-tidy @llvm/pr-subscribers-clang-tools-extra Author: Helmut Januschka (hjanuschka) Changes Adds a new check that converts std::make_* function calls to direct constructor calls using CTAD. Transforms make_optional, make_unique, make_shared and make_pair into their equivalent direct constructor calls, leveraging C++17's class template argument deduction. --- Full diff: https://github.com/llvm/llvm-project/pull/118120.diff 7 Files Affected: - (modified) clang-tools-extra/clang-tidy/modernize/CMakeLists.txt (+1) - (added) clang-tools-extra/clang-tidy/modernize/MakeFunctionToDirectCheck.cpp (+78) - (added) clang-tools-extra/clang-tidy/modernize/MakeFunctionToDirectCheck.h (+39) - (modified) clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp (+3) - (modified) clang-tools-extra/docs/ReleaseNotes.rst (+6) - (added) clang-tools-extra/docs/clang-tidy/checks/modernize/make-direct.rst (+46) - (added) clang-tools-extra/test/clang-tidy/checkers/modernize/make-direct-check.cpp (+76) ``diff diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index bab1167fb15ff..56273f914178b 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -50,6 +50,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseTransparentFunctorsCheck.cpp UseUncaughtExceptionsCheck.cpp UseUsingCheck.cpp + MakeFunctionToDirectCheck.cpp LINK_LIBS clangTidy diff --git a/clang-tools-extra/clang-tidy/modernize/MakeFunctionToDirectCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MakeFunctionToDirectCheck.cpp new file mode 100644 index 0..f9eabbaefb46f --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/MakeFunctionToDirectCheck.cpp @@ -0,0 +1,78 @@ +//===--- MakeFunctionToDirectCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MakeFunctionToDirectCheck.h" +#include "../utils/TransformerClangTidyCheck.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Tooling/Transformer/RangeSelector.h" +#include "clang/Tooling/Transformer/RewriteRule.h" +#include "clang/Tooling/Transformer/Stencil.h" + +using namespace ::clang::ast_matchers; +using namespace ::clang::transformer; + +namespace clang::tidy::modernize { + +namespace { + +RewriteRuleWith +makeFunctionToDirectCheckImpl(bool CheckMakePair, bool CheckMakeOptional, + bool CheckMakeTuple) { + std::vector> Rules; + + // Helper to create a rule for a specific make_* function + auto createRule = [](StringRef MakeFunction, StringRef DirectType) { +auto WarningMessage = cat("use class template argument deduction (CTAD) " + "instead of ", + MakeFunction); + +return makeRule( +callExpr(callee(functionDecl(hasName(MakeFunction))), + unless(hasParent(implicitCastExpr(hasImplicitDestinationType( + qualType(hasCanonicalType(qualType(asString("void") +.bind("make_call"), +changeTo(node("make_call"), + cat(DirectType, "(", callArgs("make_call"), ")")), +WarningMessage); + }; + + if (CheckMakeOptional) { +Rules.push_back(createRule("std::make_optional", "std::optional")); + } + + if (CheckMakePair) { +Rules.push_back(createRule("std::make_pair", "std::pair")); + } + + if (CheckMakeTuple) { +Rules.push_back(createRule("std::make_tuple", "std::tuple")); + } + + return applyFirst(Rules); +} + +} // namespace + +MakeFunctionToDirectCheck::MakeFunctionToDirectCheck(StringRef Name, + ClangTidyContext *Context) +: utils::TransformerClangTidyCheck(Name, Context), + CheckMakePair(Options.get("CheckMakePair", true)), + CheckMakeOptional(Options.get("CheckMakeOptional", true)), + CheckMakeTuple(Options.get("CheckMakeTuple", true)) { + setRule(makeFunctionToDirectCheckImpl(CheckMakePair, CheckMakeOptional, +CheckMakeTuple)); +} + +void MakeFunctionToDirectCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "CheckMakePair", CheckMakePair); + Options.store(Opts, "CheckMakeOptional", CheckMakeOptional); + Options.store(Opts, "CheckMakeTuple", CheckMakeTuple); +} + +} // namespace clang::tidy::modernize \ No newline at end of file diff --git a/clang-tools-extra/clang-tidy/modernize/MakeFunctionToDirectCheck.h b/clang-tools-extra/clang-tidy/modernize/MakeFunctionToDirectCheck.h new file mode 100644
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
@@ -0,0 +1,46 @@ +.. title:: clang-tidy - modernize-make-direct + +modernize-make-direct += + +Replaces ``std::make_*`` function calls with direct constructor calls using class template EugeneZelenko wrote: Please synchronize with statement in Release Notes. https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
@@ -125,6 +126,8 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck( "modernize-use-uncaught-exceptions"); CheckFactories.registerCheck("modernize-use-using"); +CheckFactories.registerCheck( +"modernize-make-direct"); vbvictor wrote: Please format alphabetically https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
@@ -50,6 +50,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseTransparentFunctorsCheck.cpp UseUncaughtExceptionsCheck.cpp UseUsingCheck.cpp + MakeFunctionToDirectCheck.cpp vbvictor wrote: Please format alphabetically https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
@@ -124,6 +124,12 @@ New checks pointer and store it as class members without handle the copy and move constructors and the assignments. +- New :doc:`modernize-make-direct ` check. + + Converts std::make_* function calls to direct constructor calls using CTAD. EugeneZelenko wrote: ```suggestion Converts ``std::make_*`` function calls to direct constructor calls using CTAD. ``` https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
@@ -124,6 +124,12 @@ New checks pointer and store it as class members without handle the copy and move constructors and the assignments. +- New :doc:`modernize-make-direct ` check. + + Converts std::make_* function calls to direct constructor calls using CTAD. + Transforms make_optional, make_pair, and make_tuple into equivalent EugeneZelenko wrote: Single sentence is enough. https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
@@ -0,0 +1,78 @@ +//===--- MakeFunctionToDirectCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MakeFunctionToDirectCheck.h" +#include "../utils/TransformerClangTidyCheck.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Tooling/Transformer/RangeSelector.h" +#include "clang/Tooling/Transformer/RewriteRule.h" +#include "clang/Tooling/Transformer/Stencil.h" + +using namespace ::clang::ast_matchers; +using namespace ::clang::transformer; + +namespace clang::tidy::modernize { + +namespace { + +RewriteRuleWith +makeFunctionToDirectCheckImpl(bool CheckMakePair, bool CheckMakeOptional, + bool CheckMakeTuple) { + std::vector> Rules; vbvictor wrote: consider using llvm::SmallVector https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
@@ -0,0 +1,46 @@ +.. title:: clang-tidy - modernize-make-direct + +modernize-make-direct vbvictor wrote: Sync check name accross all files, somewhere you have "MakeFunctionToDirect". https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
@@ -124,6 +124,12 @@ New checks pointer and store it as class members without handle the copy and move constructors and the assignments. +- New :doc:`modernize-make-direct ` check. + + Converts std::make_* function calls to direct constructor calls using CTAD. vbvictor wrote: Please sync with docs first sentence (should be identical) https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
https://github.com/vbvictor requested changes to this pull request. Generally good check idea, but needs some polishing. - Neither `modernize-make-function-to-direct` nor `modernize-make-direct` sounds clear to me (specifically `direct` part), the main purpose of this transformation is to use `CTAD`, it should be in the check name at least. `modernize-use-ctad-constructor` could be it, but I'm not 100% sure others will agree. - I don't like having many options that all do the same job. How about a list of key-value pairs of classes and their corresponding `make_` function. Something like "std::pair=std::make_pair;std::optional=std::make_optional...". Look at `readability-suspicious-call-argument.Abbreviations` for reference. - Enhance tests with type aliases, macros, template parameters https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
@@ -0,0 +1,39 @@ +//===--- MakeFunctionToDirectCheck.h - clang-tidy --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKEFUNCTIONTODIRECTCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKEFUNCTIONTODIRECTCHECK_H + +#include "../utils/TransformerClangTidyCheck.h" + +namespace clang::tidy::modernize { + +/// Converts std::make_* function calls to direct constructor calls using +/// class template argument deduction (CTAD). +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/modernize/make-direct.html +class MakeFunctionToDirectCheck : public utils::TransformerClangTidyCheck { +public: + MakeFunctionToDirectCheck(StringRef Name, ClangTidyContext *Context); + + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { +return LangOpts.CPlusPlus17; + } + + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + +private: + const bool CheckMakePair; + const bool CheckMakeOptional; + const bool CheckMakeTuple; +}; + +} // namespace clang::tidy::modernize + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKEFUNCTIONTODIRECTCHECK_H EugeneZelenko wrote: Please add newline. https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
https://github.com/hjanuschka ready_for_review https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
hjanuschka wrote: @denzor200 feedback addressed. @firewave also your feedback addressed. thank you both for your time, i kind of missed notifications for this PR https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
https://github.com/hjanuschka updated https://github.com/llvm/llvm-project/pull/118120 >From c741fffc1aa978e39946bb34efc455dc9333f993 Mon Sep 17 00:00:00 2001 From: Helmut Januschka Date: Fri, 29 Nov 2024 19:17:36 +0100 Subject: [PATCH 1/3] [clang-tidy] Add modernize-make-direct check Adds a new check that converts std::make_* function calls to direct constructor calls using CTAD. Transforms make_optional, make_unique, make_shared and make_pair into their equivalent direct constructor calls, leveraging C++17's class template argument deduction. --- .../clang-tidy/modernize/CMakeLists.txt | 1 + .../modernize/MakeFunctionToDirectCheck.cpp | 108 ++ .../modernize/MakeFunctionToDirectCheck.h | 20 .../modernize/ModernizeTidyModule.cpp | 3 + clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../modernize/modernize-make-direct.rst | 17 +++ .../checkers/modernize/make-direct-check.cpp | 66 +++ 7 files changed, 221 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/modernize/MakeFunctionToDirectCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/MakeFunctionToDirectCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/modernize-make-direct.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/make-direct-check.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index bab1167fb15ff..56273f914178b 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -50,6 +50,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseTransparentFunctorsCheck.cpp UseUncaughtExceptionsCheck.cpp UseUsingCheck.cpp + MakeFunctionToDirectCheck.cpp LINK_LIBS clangTidy diff --git a/clang-tools-extra/clang-tidy/modernize/MakeFunctionToDirectCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MakeFunctionToDirectCheck.cpp new file mode 100644 index 0..0262f77f4992c --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/MakeFunctionToDirectCheck.cpp @@ -0,0 +1,108 @@ +#include "MakeFunctionToDirectCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Type.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +void MakeFunctionToDirectCheck::registerMatchers(MatchFinder *Finder) { + if (!getLangOpts().CPlusPlus17) +return; + // Match make_xxx function calls + Finder->addMatcher(callExpr(callee(functionDecl(hasAnyName( + "std::make_optional", "std::make_unique", + "std::make_shared", "std::make_pair" + .bind("make_call"), + this); +} + +bool MakeFunctionToDirectCheck::isMakeFunction( +const std::string &FuncName) const { + static const std::array MakeFuncs = { + "make_optional", "make_unique", "make_shared", "make_pair"}; + + return std::any_of(MakeFuncs.begin(), MakeFuncs.end(), + [&](const auto &Prefix) { + return FuncName.find(Prefix) != std::string::npos; + }); +} + +std::string MakeFunctionToDirectCheck::getTemplateType( +const CXXConstructExpr *Construct) const { + if (!Construct) +return {}; + + const auto *RecordType = + dyn_cast(Construct->getType().getTypePtr()); + if (!RecordType) +return {}; + + return RecordType->getDecl()->getNameAsString(); +} + +void MakeFunctionToDirectCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Call = Result.Nodes.getNodeAs("make_call"); + if (!Call) +return; + + const auto *FuncDecl = dyn_cast(Call->getCalleeDecl()); + if (!FuncDecl || !FuncDecl->getTemplateSpecializationArgs()) +return; + + std::string FuncName = FuncDecl->getNameAsString(); + if (!isMakeFunction(FuncName)) +return; + + std::string Args; + if (Call->getNumArgs() > 0) { +SourceRange ArgRange(Call->getArg(0)->getBeginLoc(), + Call->getArg(Call->getNumArgs() - 1)->getEndLoc()); +Args = std::string(Lexer::getSourceText( +CharSourceRange::getTokenRange(ArgRange), *Result.SourceManager, +Result.Context->getLangOpts())); + } + + std::string Replacement; + if (FuncName == "make_unique" || FuncName == "make_shared") { +const auto *TemplateArgs = FuncDecl->getTemplateSpecializationArgs(); +if (!TemplateArgs || TemplateArgs->size() == 0) + return; + +QualType Type = TemplateArgs->get(0).getAsType(); +PrintingPolicy Policy(Result.Context->getLangOpts()); +Policy.SuppressTagKeyword = true; +std::string TypeStr = Type.getAsString(Policy); + +std::string SmartPtr = +(FuncName == "make_unique") ? "unique_ptr" : "
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
@@ -0,0 +1,108 @@ +#include "MakeFunctionToDirectCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Type.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +void MakeFunctionToDirectCheck::registerMatchers(MatchFinder *Finder) { + if (!getLangOpts().CPlusPlus17) +return; + // Match make_xxx function calls + Finder->addMatcher(callExpr(callee(functionDecl(hasAnyName( + "std::make_optional", "std::make_unique", + "std::make_shared", "std::make_pair" + .bind("make_call"), + this); +} + +bool MakeFunctionToDirectCheck::isMakeFunction( +const std::string &FuncName) const { + static const std::array MakeFuncs = { + "make_optional", "make_unique", "make_shared", "make_pair"}; + + return std::any_of(MakeFuncs.begin(), MakeFuncs.end(), + [&](const auto &Prefix) { + return FuncName.find(Prefix) != std::string::npos; + }); +} + +std::string MakeFunctionToDirectCheck::getTemplateType( +const CXXConstructExpr *Construct) const { + if (!Construct) +return {}; + + const auto *RecordType = + dyn_cast(Construct->getType().getTypePtr()); + if (!RecordType) +return {}; + + return RecordType->getDecl()->getNameAsString(); +} + +void MakeFunctionToDirectCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Call = Result.Nodes.getNodeAs("make_call"); + if (!Call) +return; + + const auto *FuncDecl = dyn_cast(Call->getCalleeDecl()); + if (!FuncDecl || !FuncDecl->getTemplateSpecializationArgs()) +return; + + std::string FuncName = FuncDecl->getNameAsString(); + if (!isMakeFunction(FuncName)) +return; + + std::string Args; + if (Call->getNumArgs() > 0) { +SourceRange ArgRange(Call->getArg(0)->getBeginLoc(), + Call->getArg(Call->getNumArgs() - 1)->getEndLoc()); +Args = std::string(Lexer::getSourceText( +CharSourceRange::getTokenRange(ArgRange), *Result.SourceManager, +Result.Context->getLangOpts())); + } + + std::string Replacement; + if (FuncName == "make_unique" || FuncName == "make_shared") { +const auto *TemplateArgs = FuncDecl->getTemplateSpecializationArgs(); +if (!TemplateArgs || TemplateArgs->size() == 0) + return; + +QualType Type = TemplateArgs->get(0).getAsType(); +PrintingPolicy Policy(Result.Context->getLangOpts()); +Policy.SuppressTagKeyword = true; +std::string TypeStr = Type.getAsString(Policy); + +std::string SmartPtr = +(FuncName == "make_unique") ? "unique_ptr" : "shared_ptr"; +Replacement = "std::" + SmartPtr + "(new " + TypeStr + "(" + Args + "))"; + } else { +std::string TemplateType; +if (FuncName == "make_optional") + TemplateType = "std::optional"; +else if (FuncName == "make_shared") + TemplateType = "std::shared_ptr"; +else if (FuncName == "make_pair") + TemplateType = "std::pair"; denzor200 wrote: Must be an option to specify list of template types and their make functions https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
@@ -0,0 +1,20 @@ +#include "../ClangTidyCheck.h" + +namespace clang::tidy::modernize { + +class MakeFunctionToDirectCheck : public ClangTidyCheck { denzor200 wrote: It can be refactored with `TransformerClangTidyCheck` usage. Sample for only `std::make_pair` function: ``` auto WarningMessage = cat("use class template argument deduction (CTAD) " "instead of std::make_pair"); return makeRule( declStmt(hasSingleDecl(varDecl( hasType(autoType()), hasTypeLoc(typeLoc().bind("auto_type_loc")), hasInitializer(hasDescendant( callExpr(callee(functionDecl(hasName("std::make_pair" .bind("make_call")), {changeTo(node("auto_type_loc"), cat("std::pair")), changeTo(node("make_call"), cat("{", callArgs("make_call"), "}"))}, WarningMessage); ``` Look at "abseil-cleanup-ctad" check's internals for more details. I'm not sure is it possible to change `make_unique` and `make_shared` using this method, but they should not be in this check as it mentioned before(or at least they must be hidded via option). BTW it will produce better FixItHint: ``` - auto p1 = std::make_pair(1, "test"); + std::pair p1 = {1, "test"}; ``` https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
https://github.com/denzor200 requested changes to this pull request. https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
@@ -0,0 +1,17 @@ +.. title:: clang-tidy - modernize-make-direct + +modernize-make-direct + + +Replaces ``std::make_*`` function calls with direct constructor calls using class template +argument deduction (CTAD). + +== + Before After +-- +``std::make_optional(42)````std::optional(42)`` +``std::make_unique(1)````std::unique_ptr(new Widget(1))`` +``std::make_shared(2)````std::shared_ptr(new Widget(2))`` +``std::make_pair(1, "test")`` ``std::pair(1, "test")`` denzor200 wrote: forgot about ``std::make_tuple(1, "test")`` ``std::tuple(1, "test")`` https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
firewave wrote: This will conflict with `modernize-make-shared` and `modernize-make-unique`. I also very sure having `new` any modern C++ code is very much to be avoided. Having no insight on the differences of the inner workings - but just based on https://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared#Notes this appears to be something behaving very differently and less optimal/safe. https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
https://github.com/hjanuschka created https://github.com/llvm/llvm-project/pull/118120 Adds a new check that converts std::make_* function calls to direct constructor calls using CTAD. Transforms make_optional, make_unique, make_shared and make_pair into their equivalent direct constructor calls, leveraging C++17's class template argument deduction. >From 2bcf868d023b5be2f3c88f1d68dd2084b7db4604 Mon Sep 17 00:00:00 2001 From: Helmut Januschka Date: Fri, 29 Nov 2024 19:17:36 +0100 Subject: [PATCH] [clang-tidy] Add modernize-make-direct check Adds a new check that converts std::make_* function calls to direct constructor calls using CTAD. Transforms make_optional, make_unique, make_shared and make_pair into their equivalent direct constructor calls, leveraging C++17's class template argument deduction. --- .../clang-tidy/modernize/CMakeLists.txt | 1 + .../modernize/MakeFunctionToDirectCheck.cpp | 108 ++ .../modernize/MakeFunctionToDirectCheck.h | 20 .../modernize/ModernizeTidyModule.cpp | 3 + clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../modernize/modernize-make-direct.rst | 17 +++ .../checkers/modernize/make-direct-check.cpp | 66 +++ 7 files changed, 221 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/modernize/MakeFunctionToDirectCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/MakeFunctionToDirectCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/modernize-make-direct.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/make-direct-check.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index c919d49b42873a..7e8d9296c6a64c 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -49,6 +49,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseTransparentFunctorsCheck.cpp UseUncaughtExceptionsCheck.cpp UseUsingCheck.cpp + MakeFunctionToDirectCheck.cpp LINK_LIBS clangTidy diff --git a/clang-tools-extra/clang-tidy/modernize/MakeFunctionToDirectCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MakeFunctionToDirectCheck.cpp new file mode 100644 index 00..0262f77f4992cb --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/MakeFunctionToDirectCheck.cpp @@ -0,0 +1,108 @@ +#include "MakeFunctionToDirectCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Type.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +void MakeFunctionToDirectCheck::registerMatchers(MatchFinder *Finder) { + if (!getLangOpts().CPlusPlus17) +return; + // Match make_xxx function calls + Finder->addMatcher(callExpr(callee(functionDecl(hasAnyName( + "std::make_optional", "std::make_unique", + "std::make_shared", "std::make_pair" + .bind("make_call"), + this); +} + +bool MakeFunctionToDirectCheck::isMakeFunction( +const std::string &FuncName) const { + static const std::array MakeFuncs = { + "make_optional", "make_unique", "make_shared", "make_pair"}; + + return std::any_of(MakeFuncs.begin(), MakeFuncs.end(), + [&](const auto &Prefix) { + return FuncName.find(Prefix) != std::string::npos; + }); +} + +std::string MakeFunctionToDirectCheck::getTemplateType( +const CXXConstructExpr *Construct) const { + if (!Construct) +return {}; + + const auto *RecordType = + dyn_cast(Construct->getType().getTypePtr()); + if (!RecordType) +return {}; + + return RecordType->getDecl()->getNameAsString(); +} + +void MakeFunctionToDirectCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Call = Result.Nodes.getNodeAs("make_call"); + if (!Call) +return; + + const auto *FuncDecl = dyn_cast(Call->getCalleeDecl()); + if (!FuncDecl || !FuncDecl->getTemplateSpecializationArgs()) +return; + + std::string FuncName = FuncDecl->getNameAsString(); + if (!isMakeFunction(FuncName)) +return; + + std::string Args; + if (Call->getNumArgs() > 0) { +SourceRange ArgRange(Call->getArg(0)->getBeginLoc(), + Call->getArg(Call->getNumArgs() - 1)->getEndLoc()); +Args = std::string(Lexer::getSourceText( +CharSourceRange::getTokenRange(ArgRange), *Result.SourceManager, +Result.Context->getLangOpts())); + } + + std::string Replacement; + if (FuncName == "make_unique" || FuncName == "make_shared") { +const auto *TemplateArgs = FuncDecl->getTemplateSpecializationArgs(); +if (!TemplateArgs || TemplateArgs->size() == 0) + return; + +QualType Type = T
[clang-tools-extra] [clang-tidy] Add modernize-make-direct check (PR #118120)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff 056153f36eca184f81969f5cd5c8cd967c935f96 2bcf868d023b5be2f3c88f1d68dd2084b7db4604 --extensions h,cpp -- clang-tools-extra/clang-tidy/modernize/MakeFunctionToDirectCheck.cpp clang-tools-extra/clang-tidy/modernize/MakeFunctionToDirectCheck.h clang-tools-extra/test/clang-tidy/checkers/modernize/make-direct-check.cpp clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp `` View the diff from clang-format here. ``diff diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 45754f0a0b..55a2deeba0 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -124,7 +124,7 @@ public: "modernize-use-uncaught-exceptions"); CheckFactories.registerCheck("modernize-use-using"); CheckFactories.registerCheck( -"modernize-make-direct"); +"modernize-make-direct"); } }; `` https://github.com/llvm/llvm-project/pull/118120 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits