10 #include "clang/AST/ASTContext.h" 11 #include "clang/ASTMatchers/ASTMatchFinder.h" 12 #include "clang/Lex/Lexer.h" 13 #include "llvm/ADT/StringRef.h" 21 void ShrinkToFitCheck::registerMatchers(MatchFinder *Finder) {
22 if (!getLangOpts().CPlusPlus11)
27 const auto ShrinkableAsMember =
28 memberExpr(member(valueDecl().bind(
"ContainerDecl")));
29 const auto ShrinkableAsDecl =
30 declRefExpr(hasDeclaration(valueDecl().bind(
"ContainerDecl")));
31 const auto CopyCtorCall = cxxConstructExpr(hasArgument(
32 0, anyOf(ShrinkableAsMember, ShrinkableAsDecl,
33 unaryOperator(has(ignoringParenImpCasts(ShrinkableAsMember))),
34 unaryOperator(has(ignoringParenImpCasts(ShrinkableAsDecl))))));
35 const auto SwapParam =
36 expr(anyOf(memberExpr(member(equalsBoundNode(
"ContainerDecl"))),
37 declRefExpr(hasDeclaration(equalsBoundNode(
"ContainerDecl"))),
38 unaryOperator(has(ignoringParenImpCasts(
39 memberExpr(member(equalsBoundNode(
"ContainerDecl")))))),
40 unaryOperator(has(ignoringParenImpCasts(declRefExpr(
41 hasDeclaration(equalsBoundNode(
"ContainerDecl"))))))));
45 on(hasType(hasCanonicalType(hasDeclaration(namedDecl(
46 hasAnyName(
"std::basic_string",
"std::deque",
"std::vector")))))),
47 callee(cxxMethodDecl(hasName(
"swap"))),
48 has(ignoringParenImpCasts(memberExpr(hasDescendant(CopyCtorCall)))),
49 hasArgument(0, SwapParam.bind(
"ContainerToShrink")),
50 unless(isInTemplateInstantiation()))
51 .bind(
"CopyAndSwapTrick"),
55 void ShrinkToFitCheck::check(
const MatchFinder::MatchResult &
Result) {
56 const auto *MemberCall =
57 Result.Nodes.getNodeAs<CXXMemberCallExpr>(
"CopyAndSwapTrick");
58 const auto *Container = Result.Nodes.getNodeAs<Expr>(
"ContainerToShrink");
61 if (!MemberCall->getBeginLoc().isMacroID()) {
62 const LangOptions &Opts = getLangOpts();
63 std::string ReplacementText;
64 if (
const auto *UnaryOp = llvm::dyn_cast<UnaryOperator>(Container)) {
67 UnaryOp->getSubExpr()->getSourceRange()),
68 *Result.SourceManager, Opts);
69 ReplacementText +=
"->shrink_to_fit()";
71 ReplacementText = Lexer::getSourceText(
73 *Result.SourceManager, Opts);
74 ReplacementText +=
".shrink_to_fit()";
77 Hint = FixItHint::CreateReplacement(MemberCall->getSourceRange(),
81 diag(MemberCall->getBeginLoc(),
"the shrink_to_fit method should be used " 82 "to reduce the capacity of a shrinkable "
llvm::Optional< Range > getTokenRange(const SourceManager &SM, const LangOptions &LangOpts, SourceLocation TokLoc)
Returns the taken range at TokLoc.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result