26 auto LockType = templateSpecializationType(
30 StatementMatcher Lock =
31 declStmt(has(varDecl(hasType(LockType)).bind(
"lock-decl")))
32 .bind(
"lock-decl-stmt");
34 expr(anyOf(coawaitExpr(), coyieldExpr(), dependentCoawaitExpr()),
35 forCallable(functionDecl().bind(
"function")),
36 unless(isInTemplateInstantiation()),
38 compoundStmt(has(Lock), forCallable(equalsBoundNode(
"function")))
45 const auto *
Block = Result.Nodes.getNodeAs<CompoundStmt>(
"block");
46 const auto *Suspend = Result.Nodes.getNodeAs<Expr>(
"suspend");
47 const auto *LockDecl = Result.Nodes.getNodeAs<VarDecl>(
"lock-decl");
48 const auto *LockStmt = Result.Nodes.getNodeAs<Stmt>(
"lock-decl-stmt");
50 if (!
Block || !Suspend || !LockDecl || !LockStmt)
53 ASTContext &Context = *Result.Context;
54 CFG::BuildOptions Options;
55 Options.AddImplicitDtors =
true;
56 Options.AddTemporaryDtors =
true;
58 std::unique_ptr<CFG> TheCFG = CFG::buildCFG(
59 nullptr,
const_cast<clang::CompoundStmt *
>(
Block), &Context, Options);
64 const Stmt *LastBlockStmt =
Block->body_back();
66 (Suspend == LastBlockStmt ||
67 Sequence.
inSequence(Suspend, LastBlockStmt))) {
68 diag(Suspend->getBeginLoc(),
"coroutine suspended with lock %0 held")