================ @@ -53,18 +53,76 @@ AST_MATCHER(ParmVarDecl, isTemplateTypeParameter) { FuncTemplate->getTemplateParameters()->getDepth(); } +AST_MATCHER_P(NamedDecl, hasSameNameAsBoundNode, std::string, BindingID) { + const auto &Name = Node.getNameAsString(); + + return Builder->removeBindings( + [this, Name](const ast_matchers::internal::BoundNodesMap &Nodes) { + const auto &BN = Nodes.getNode(this->BindingID); + if (const auto *ND = BN.get<NamedDecl>()) { + if (!isa<FieldDecl, CXXMethodDecl, VarDecl>(ND)) + return true; + return ND->getName() != Name; + } + return true; + }); +} + +AST_MATCHER_P(LambdaCapture, hasCaptureKind, LambdaCaptureKind, Kind) { + return Node.getCaptureKind() == Kind; +} + +AST_MATCHER_P(LambdaExpr, hasCaptureDefaultKind, LambdaCaptureDefault, Kind) { + return Node.getCaptureDefault() == Kind; +} + +AST_MATCHER(LambdaExpr, hasCaptureToParm) { + auto RefToParm = capturesVar(varDecl(hasSameNameAsBoundNode("param"))); + auto HasRefToParm = hasAnyCapture(RefToParm); + + auto CaptureInRef = + allOf(hasCaptureDefaultKind(LambdaCaptureDefault::LCD_ByRef), + unless(HasRefToParm)); + auto CaptureInCopy = allOf( + hasCaptureDefaultKind(LambdaCaptureDefault::LCD_ByCopy), HasRefToParm); + auto CaptureByRefExplicit = hasAnyCapture( + allOf(hasCaptureKind(LambdaCaptureKind::LCK_ByRef), RefToParm)); + + auto Captured = + lambdaExpr(anyOf(CaptureInRef, CaptureInCopy, CaptureByRefExplicit)); + if (Captured.matches(Node, Finder, Builder)) + return true; + + return false; +} + +AST_MATCHER(CallExpr, forCallableNode) { ---------------- PiotrZSL wrote:
In general I'm not fun of creating new matchers in existing matchers, mainly because those matchers will be created on every invocation and that will slow down a checker. Better way is to do a trick with InnerMatcher like in possiblyPackExpansionOf, and inject those matchers from outside or unwind macher. for example forCallableNode would look like this: ``` auto InvokeInCaptureList = hasAnyCapture(capturesVar( varDecl(hasInitializer(ignoringParenImpCasts(equalsBoundNode("call")))))); auto InvokeInLambda = hasDeclContext(cxxRecordDecl(isLambda(), hasParent(lambdaExpr(forCallable(equalsBoundNode("func")), anyOf(InvokeInCaptureList, hasCaptureToParm()))))); Use: expr(expr().bind("call"), forCallable(anyOf(equalsBoundNode("func"), InvokeInLambda))) ``` https://github.com/llvm/llvm-project/pull/77056 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits