10#include "clang/AST/ASTContext.h"
11#include "clang/Lex/Lexer.h"
18AST_MATCHER(CXXRecordDecl, hasNonTrivialDestructor) {
20 return Node.hasDefinition() &&
Node.hasNonTrivialDestructor();
28 mapAnyOf(cxxConstructExpr, cxxUnresolvedConstructExpr)
29 .with(hasParent(compoundStmt().bind(
"compound")),
30 anyOf(hasType(hasCanonicalType(recordType(hasDeclaration(
31 cxxRecordDecl(hasNonTrivialDestructor()))))),
32 hasType(hasCanonicalType(templateSpecializationType(
33 hasDeclaration(classTemplateDecl(has(
34 cxxRecordDecl(hasNonTrivialDestructor())))))))))
41 bool DefaultConstruction) {
42 const char *Replacement =
" give_me_a_name";
46 if (DefaultConstruction) {
47 D << FixItHint::CreateReplacement(CharSourceRange::getTokenRange(SR),
55 D << FixItHint::CreateInsertion(SR.getBegin(), Replacement);
59 const auto *
E = Result.Nodes.getNodeAs<Expr>(
"expr");
63 if (
E->getBeginLoc().isMacroID())
68 const auto *CS = Result.Nodes.getNodeAs<CompoundStmt>(
"compound");
69 const auto *LastExpr = dyn_cast<Expr>(CS->body_back());
71 if (LastExpr &&
E == LastExpr->IgnoreUnlessSpelledInSource())
75 auto D =
diag(
E->getBeginLoc(),
"object destroyed immediately after "
76 "creation; did you mean to name the object?");
78 if (
const auto *
Node = dyn_cast<CXXConstructExpr>(
E))
80 Node->getNumArgs() == 0 ||
81 isa<CXXDefaultArgExpr>(
Node->getArg(0)));
82 if (
const auto *
Node = dyn_cast<CXXUnresolvedConstructExpr>(
E)) {
83 auto SR = SourceRange(
Node->getLParenLoc(),
Node->getRParenLoc());
84 auto DefaultConstruction =
Node->getNumArgs() == 0;
85 if (!DefaultConstruction) {
86 auto *FirstArg =
Node->getArg(0);
87 DefaultConstruction = isa<CXXDefaultArgExpr>(FirstArg);
88 if (
auto *ILE = dyn_cast<InitListExpr>(FirstArg)) {
89 DefaultConstruction = ILE->getNumInits() == 0;
90 SR = SourceRange(ILE->getLBraceLoc(), ILE->getRBraceLoc());
::clang::DynTypedNode Node
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register AST matchers with Finder.
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
AST_MATCHER(clang::VarDecl, hasConstantDeclaration)
void reportDiagnostic(DiagnosticBuilder D, const T *Node, SourceRange SR, bool DefaultConstruction)