11#include "clang/AST/Type.h" 
   12#include "clang/AST/TypeLoc.h" 
   13#include "clang/Basic/LLVM.h" 
   14#include "llvm/Support/Error.h" 
   39class ExpandDeducedType : 
public Tweak {
 
   41  const char *id() const final;
 
   42  llvm::StringLiteral kind()
 const override {
 
   45  bool prepare(
const Selection &Inputs) 
override;
 
   46  Expected<Effect> apply(
const Selection &Inputs) 
override;
 
   47  std::string title() 
const override;
 
   55std::string ExpandDeducedType::title()
 const {
 
   56  return "Replace with deduced type";
 
   61bool isStructuredBindingType(
const SelectionTree::Node *N) {
 
   63  while (N && N->ASTNode.get<TypeLoc>())
 
   66  return N && N->ASTNode.get<DecompositionDecl>();
 
   69bool isLambda(QualType QT) {
 
   71    if (
const auto *RD = QT->getAsRecordDecl())
 
   72      return RD->isLambda();
 
   78bool isDeducedAsLambda(
const SelectionTree::Node *Node, SourceLocation Loc) {
 
   83  for (
const auto *It = Node; It; It = It->Parent) {
 
   84    if (
const auto *DD = It->ASTNode.get<DeclaratorDecl>()) {
 
   85      if (DD->getTypeSourceInfo() &&
 
   86          DD->getTypeSourceInfo()->getTypeLoc().getBeginLoc() == Loc &&
 
   87          isLambda(DD->getType()))
 
   96bool isTemplateParam(
const SelectionTree::Node *Node) {
 
   98    if (Node->Parent->ASTNode.get<NonTypeTemplateParmDecl>())
 
  103bool ExpandDeducedType::prepare(
const Selection &Inputs) {
 
  104  if (
auto *Node = Inputs.ASTSelection.commonAncestor()) {
 
  105    if (
auto *TypeNode = Node->ASTNode.get<TypeLoc>()) {
 
  106      if (
const AutoTypeLoc Result = TypeNode->getAs<AutoTypeLoc>()) {
 
  107        if (!isStructuredBindingType(Node) &&
 
  108            !isDeducedAsLambda(Node, Result.getBeginLoc()) &&
 
  109            !isTemplateParam(Node))
 
  110          Range = Result.getSourceRange();
 
  112      if (
auto TTPAuto = TypeNode->getAs<TemplateTypeParmTypeLoc>()) {
 
  117        if (TTPAuto.getDecl()->isImplicit() &&
 
  118            !TTPAuto.getDecl()->hasTypeConstraint())
 
  119          Range = TTPAuto.getSourceRange();
 
  122      if (
auto DTTL = TypeNode->getAs<DecltypeTypeLoc>()) {
 
  123        if (!isLambda(cast<DecltypeType>(DTTL.getType())->getUnderlyingType()))
 
  124          Range = DTTL.getSourceRange();
 
  129  return Range.isValid();
 
  132Expected<Tweak::Effect> ExpandDeducedType::apply(
const Selection &Inputs) {
 
  133  auto &SrcMgr = Inputs.AST->getSourceManager();
 
  135  std::optional<clang::QualType> DeducedType =
 
  137                     Inputs.AST->getHeuristicResolver(), Range.getBegin());
 
  140  if (DeducedType == std::nullopt || (*DeducedType)->isUndeducedAutoType())
 
  141    return error(
"Could not deduce type for 'auto' type");
 
  150  if ((*DeducedType)->isDependentType())
 
  151    return error(
"Could not expand a dependent type");
 
  158  std::string PrettyDeclarator = 
printType(
 
  159      *DeducedType, Inputs.ASTSelection.commonAncestor()->getDeclContext(),
 
  161  llvm::StringRef PrettyTypeName = PrettyDeclarator;
 
  162  if (!PrettyTypeName.consume_back(
"DECLARATOR_ID"))
 
  163    return error(
"Could not expand type that isn't a simple string");
 
  164  PrettyTypeName = PrettyTypeName.rtrim();
 
  166  tooling::Replacement Expansion(SrcMgr, CharSourceRange(Range, 
true),
 
  169  return Effect::mainFileEdit(SrcMgr, tooling::Replacements(Expansion));
 
#define REGISTER_TWEAK(Subclass)
 
An interface base for small context-sensitive refactoring actions.
 
llvm::Error error(std::error_code, std::string &&)
 
FIXME: Skip testing on windows temporarily due to the different escaping code mode.
 
std::string printType(const QualType QT, const DeclContext &CurContext, const llvm::StringRef Placeholder, bool FullyQualify)
Returns a QualType as string.
 
std::optional< QualType > getDeducedType(ASTContext &ASTCtx, const HeuristicResolver *Resolver, SourceLocation Loc)
Retrieves the deduced type at a given location (auto, decltype).
 
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
 
static const llvm::StringLiteral REFACTOR_KIND