10 #include "clang/AST/ASTContext.h" 11 #include "clang/Lex/Lexer.h" 20 AST_MATCHER(CXXRecordDecl, hasNonTrivialDestructor) {
22 return Node.hasDefinition() && Node.hasNonTrivialDestructor();
26 void UnusedRaiiCheck::registerMatchers(MatchFinder *Finder) {
29 if (!getLangOpts().CPlusPlus)
36 cxxBindTemporaryExpr(unless(has(ignoringParenImpCasts(callExpr()))))
39 exprWithCleanups(unless(isInTemplateInstantiation()),
40 hasParent(compoundStmt().bind(
"compound")),
41 hasType(cxxRecordDecl(hasNonTrivialDestructor())),
42 anyOf(has(ignoringParenImpCasts(BindTemp)),
43 has(ignoringParenImpCasts(cxxFunctionalCastExpr(
44 has(ignoringParenImpCasts(BindTemp)))))))
49 void UnusedRaiiCheck::check(
const MatchFinder::MatchResult &
Result) {
50 const auto *E = Result.Nodes.getNodeAs<Expr>(
"expr");
54 if (E->getBeginLoc().isMacroID())
59 const auto *CS = Result.Nodes.getNodeAs<CompoundStmt>(
"compound");
60 if (E == CS->body_back())
64 auto D = diag(E->getBeginLoc(),
"object destroyed immediately after " 65 "creation; did you mean to name the object?");
66 const char *Replacement =
" give_me_a_name";
70 const auto *BTE = Result.Nodes.getNodeAs<CXXBindTemporaryExpr>(
"temp");
71 if (
const auto *TOE = dyn_cast<CXXTemporaryObjectExpr>(BTE->getSubExpr()))
72 if (TOE->getNumArgs() == 0) {
73 D << FixItHint::CreateReplacement(
83 match(expr(hasDescendant(typeLoc().bind(
"t"))), *E, *Result.Context);
84 const auto *TL = selectFirst<TypeLoc>(
"t", Matches);
85 D << FixItHint::CreateInsertion(
86 Lexer::getLocForEndOfToken(TL->getEndLoc(), 0, *Result.SourceManager,
AST_MATCHER(Expr, isMacroID)
std::vector< std::string > match(const SymbolIndex &I, const FuzzyFindRequest &Req, bool *Incomplete)
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