10#include "clang/AST/ASTContext.h"
18 ast_matchers::internal::Matcher<Stmt>, InnerMatcher) {
19 const Stmt *E = &Node;
22 if (
const auto *EWC = dyn_cast<ExprWithCleanups>(E))
23 E = EWC->getSubExpr();
25 else if (
const auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E))
26 E = BTE->getSubExpr();
28 else if (
const auto *FCE = dyn_cast<CXXFunctionalCastExpr>(E))
29 E = FCE->getSubExpr();
34 return InnerMatcher.matches(*E, Finder, Builder);
38AST_MATCHER_P(CXXRecordDecl, baseOfBoundNode, std::string, ID) {
39 return Builder->removeBindings(
40 [&](
const ast_matchers::internal::BoundNodesMap &Nodes) {
41 const auto *Derived = Nodes.getNodeAs<CXXRecordDecl>(ID);
42 return Derived != &Node && !Derived->isDerivedFrom(&Node);
57 compoundStmt(hasParent(cxxConstructorDecl(
58 ofClass(cxxRecordDecl().bind(
"parent")))),
59 forEach(ignoringTemporaryExpr(
61 hasDeclaration(cxxConstructorDecl(ofClass(
62 cxxRecordDecl(baseOfBoundNode(
"parent"))))))
64 unless(isInTemplateInstantiation()))),
69 const MatchFinder::MatchResult &Result) {
70 const auto *E = Result.Nodes.getNodeAs<CXXConstructExpr>(
"construct");
71 diag(E->getBeginLoc(),
"did you intend to call a delegated constructor? "
72 "A temporary object is created here instead");
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
void registerMatchers(ast_matchers::MatchFinder *Finder) override
AST_MATCHER_P(Stmt, isStatementIdenticalToBoundNode, std::string, ID)