12 #include "clang/AST/Type.h"
13 #include "clang/AST/TypeLoc.h"
14 #include "clang/Basic/LLVM.h"
15 #include "llvm/ADT/None.h"
16 #include "llvm/ADT/Optional.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/Error.h"
37 class ExpandAutoType :
public Tweak {
39 const char *id() const final;
40 Intent intent()
const override {
return Intent::Refactor;}
41 bool prepare(
const Selection &
Inputs)
override;
42 Expected<Effect> apply(
const Selection &
Inputs)
override;
43 std::string title()
const override;
47 llvm::Optional<clang::AutoTypeLoc> CachedLocation;
57 std::string ExpandAutoType::title()
const {
return "Expand auto type"; }
59 bool ExpandAutoType::prepare(
const Selection&
Inputs) {
61 if (
auto *Node =
Inputs.ASTSelection.commonAncestor()) {
62 if (
auto *TypeNode = Node->ASTNode.get<TypeLoc>()) {
63 if (
const AutoTypeLoc Result = TypeNode->getAs<AutoTypeLoc>()) {
65 if (!Result.getTypePtr()->isDecltypeAuto())
66 CachedLocation = Result;
70 return (
bool) CachedLocation;
73 Expected<Tweak::Effect> ExpandAutoType::apply(
const Selection&
Inputs) {
74 auto &SrcMgr =
Inputs.AST->getSourceManager();
77 Inputs.AST->getASTContext(), CachedLocation->getBeginLoc());
81 return createErrorMessage(
"Could not deduce type for 'auto' type",
Inputs);
85 dyn_cast<RecordType>(*DeducedType)->getDecl()->isLambda()) {
86 return createErrorMessage(
"Could not expand type of lambda expression",
93 if (
DeducedType->getTypePtr()->isFunctionPointerType()) {
94 return createErrorMessage(
"Could not expand type of function pointer",
99 Inputs.ASTSelection.commonAncestor()->getDeclContext());
102 Expansion(SrcMgr, CharSourceRange(CachedLocation->getSourceRange(),
true),
105 return Effect::mainFileEdit(SrcMgr, tooling::Replacements(Expansion));
109 const Selection&
Inputs) {
110 auto &SrcMgr =
Inputs.AST->getSourceManager();
111 std::string ErrorMessage =
113 SrcMgr.getFilename(
Inputs.Cursor).str() +
" Line " +
114 std::to_string(SrcMgr.getExpansionLineNumber(
Inputs.Cursor));
116 return llvm::createStringError(llvm::inconvertibleErrorCode(),
117 ErrorMessage.c_str());