================
@@ -0,0 +1,352 @@
+//===-- AbbreviateFunctionTemplate.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 "XRefs.h"
+#include "refactor/Tweak.h"
+#include "support/Logger.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Tooling/Core/Replacement.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include <numeric>
+
+namespace clang {
+namespace clangd {
+namespace {
+/// Converts a function template to its abbreviated form using auto parameters.
+/// Before:
+///     template <std::integral T>
+///     auto foo(T param) { }
+///          ^^^^^^^^^^^
+/// After:
+///     auto foo(std::integral auto param) { }
+class AbbreviateFunctionTemplate : public Tweak {
+public:
+  const char *id() const final;
+
+  bool prepare(const Selection &Inputs) override;
+  Expected<Effect> apply(const Selection &Inputs) override;
+
+  std::string title() const override {
+    return llvm::formatv("Abbreviate function template");
+  }
+
+  llvm::StringLiteral kind() const override {
+    return CodeAction::REFACTOR_KIND;
+  }
+
+private:
+  static const char *AutoKeywordSpelling;
+  const FunctionTemplateDecl *FunctionTemplateDeclaration;
+
+  struct TemplateParameterInfo {
+    const TypeConstraint *Constraint;
+    unsigned int FunctionParameterIndex;
+    llvm::SmallVector<tok::TokenKind> FunctionParameterQualifiers;
+    llvm::SmallVector<tok::TokenKind> FunctionParameterTypeQualifiers;
+  };
+
+  llvm::SmallVector<TemplateParameterInfo> TemplateParameterInfoList;
+
+  bool traverseFunctionParameters(size_t NumberOfTemplateParameters);
+
+  llvm::Expected<tooling::Replacements>
+  generateFunctionParameterReplacements(const ASTContext &Context);
+
+  llvm::Expected<tooling::Replacement> generateFunctionParameterReplacement(
+      const TemplateParameterInfo &TemplateParameterInfo,
+      const ASTContext &Context);
+
+  llvm::Expected<tooling::Replacement>
+  generateTemplateDeclarationReplacement(const ASTContext &Context);
+
+  static std::tuple<QualType, llvm::SmallVector<tok::TokenKind>,
+                    llvm::SmallVector<tok::TokenKind>>
+  deconstructType(QualType Type);
+};
+
+REGISTER_TWEAK(AbbreviateFunctionTemplate)
+
+const char *AbbreviateFunctionTemplate::AutoKeywordSpelling =
+    getKeywordSpelling(tok::kw_auto);
+
+template <typename T>
+const T *findDeclaration(const SelectionTree::Node &Root) {
+  for (const auto *Node = &Root; Node; Node = Node->Parent) {
+    if (const T *Result = dyn_cast_or_null<T>(Node->ASTNode.get<Decl>()))
+      return Result;
+  }
+
+  return nullptr;
+}
+
+const char *getSpellingForQualifier(tok::TokenKind const &Qualifier) {
+  if (const auto *Spelling = getKeywordSpelling(Qualifier))
+    return Spelling;
+
+  if (const auto *Spelling = getPunctuatorSpelling(Qualifier))
+    return Spelling;
+
+  return nullptr;
+}
+
+bool AbbreviateFunctionTemplate::prepare(const Selection &Inputs) {
+  const auto *CommonAncestor = Inputs.ASTSelection.commonAncestor();
+  if (!CommonAncestor)
+    return false;
+
+  FunctionTemplateDeclaration =
+      findDeclaration<FunctionTemplateDecl>(*CommonAncestor);
----------------
timon-ul wrote:

I am not the most knowledgeable on this, but for example in DefineOutline.cpp 
next to this file there is a `getSelectedFunction()` function which seems to 
also "solve" the same problem (for `FunctionDecl`). I think we can do it the 
same way for `FunctionTemplateDecl` which I would prefer since it seems to be 
the desired way of checking for this (unless there is some reason as to why 
this does not work here). (Also not sure why in the comment of it they talked 
about not having a place where they can add a common header, what stops them 
from just adding one??)

https://github.com/llvm/llvm-project/pull/74710
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to