[clang-tools-extra] [clangd] Add tweak to inline concept requirements (PR #69693)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 23 02:24:10 PDT 2026
================
@@ -0,0 +1,265 @@
+//===--- InlineConceptRequirement.cpp ----------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+#include "ParsedAST.h"
+#include "SourceCode.h"
+#include "refactor/Tweak.h"
+#include "support/Logger.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ExprConcepts.h"
+#include "clang/Tooling/Core/Replacement.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Error.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+/// Inlines a concept requirement.
+///
+/// Before:
+/// template <typename T> void f(T) requires foo<T> {}
+/// ^^^^^^
+/// After:
+/// template <foo T> void f(T) {}
+class InlineConceptRequirement : public Tweak {
+public:
+ const char *id() const final;
+
+ auto prepare(const Selection &Inputs) -> bool override;
+ auto apply(const Selection &Inputs) -> Expected<Effect> override;
+ auto title() const -> std::string override {
+ return "Inline concept requirement";
+ }
+ auto kind() const -> llvm::StringLiteral override {
+ return CodeAction::REFACTOR_KIND;
+ }
+
+private:
+ const ConceptSpecializationExpr *ConceptSpecializationExpression;
+ const TemplateTypeParmDecl *TemplateTypeParameterDeclaration;
+ const syntax::Token *RequiresToken;
+
+ static auto getTemplateParameterIndexOfTemplateArgument(
+ const TemplateArgument &TemplateArgument) -> std::optional<int>;
+ auto generateRequiresReplacement(ASTContext &)
+ -> llvm::Expected<tooling::Replacement>;
+ auto generateRequiresTokenReplacement(const syntax::TokenBuffer &)
+ -> tooling::Replacement;
+ auto generateTemplateParameterReplacement(ASTContext &Context)
+ -> llvm::Expected<tooling::Replacement>;
+
+ static auto findToken(const ParsedAST *, const SourceRange &,
+ const tok::TokenKind) -> const syntax::Token *;
+
+ template <typename T, typename NodeKind>
+ static auto findNode(const SelectionTree::Node &Root)
+ -> std::tuple<const T *, const SelectionTree::Node *>;
+
+ template <typename T>
+ static auto findExpression(const SelectionTree::Node &Root)
+ -> std::tuple<const T *, const SelectionTree::Node *> {
+ return findNode<T, Expr>(Root);
+ }
+
+ template <typename T>
+ static auto findDeclaration(const SelectionTree::Node &Root)
+ -> std::tuple<const T *, const SelectionTree::Node *> {
+ return findNode<T, Decl>(Root);
+ }
+};
+
+REGISTER_TWEAK(InlineConceptRequirement)
+
+auto InlineConceptRequirement::prepare(const Selection &Inputs) -> bool {
+ // Check if C++ version is 20 or higher
+ if (!Inputs.AST->getLangOpts().CPlusPlus20)
----------------
timon-ul wrote:
This works exactly only if the user has Cpp20, if they are on Cpp23 this tweak will not surface, which I guess is undesired. I do not know the exact check, but I assume there is a proper way to figure out if concepts are enabled (or if we are at least Cpp20).
https://github.com/llvm/llvm-project/pull/69693
More information about the cfe-commits
mailing list