Lines Matching +full:- +full:lp
1 //===--- AvoidBindCheck.cpp - clang-tidy-----------------------------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
51 CMK_Function, // callable is the name of a member or non-member function.
120 return ignoreTemporariesAndPointers(T->getSubExpr()); in ignoreTemporariesAndPointers()
122 const Expr *F = E->IgnoreImplicit(); in ignoreTemporariesAndPointers()
131 return ignoreTemporariesAndConstructors(T->getArg(0)); in ignoreTemporariesAndConstructors()
133 const Expr *F = E->IgnoreImplicit(); in ignoreTemporariesAndConstructors()
143 CharSourceRange::getTokenRange(E->getBeginLoc(), E->getEndLoc()), in getSourceTextForExpr()
144 *Result.SourceManager, Result.Context->getLangOpts()); in getSourceTextForExpr()
148 const auto *CE = dyn_cast<CallExpr>(E->IgnoreImplicit()); in isCallExprNamed()
151 const auto *ND = dyn_cast<NamedDecl>(CE->getCalleeDecl()); in isCallExprNamed()
154 return ND->getQualifiedNameAsString() == Name; in isCallExprNamed()
164 if (tryCaptureAsLocalVariable(Result, B, CE->getArg(0)) || in initializeBindArgumentForCallExpr()
165 tryCaptureAsMemberVariable(Result, B, CE->getArg(0))) { in initializeBindArgumentForCallExpr()
174 B.SourceTokens = getSourceTextForExpr(Result, CE->getArg(0)); in initializeBindArgumentForCallExpr()
187 const ValueDecl *Decl = DeclRef->getDecl(); in anyDescendantIsLocal()
189 if (Var->isLocalVarDeclOrParm()) in anyDescendantIsLocal()
195 return any_of(Statement->children(), anyDescendantIsLocal); in anyDescendantIsLocal()
201 if (const auto *CE = dyn_cast<CXXConstructExpr>(BTE->getSubExpr())) in tryCaptureAsLocalVariable()
202 return tryCaptureAsLocalVariable(Result, B, CE->getArg(0)); in tryCaptureAsLocalVariable()
206 const auto *DRE = dyn_cast<DeclRefExpr>(E->IgnoreImplicit()); in tryCaptureAsLocalVariable()
210 const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()); in tryCaptureAsLocalVariable()
211 if (!VD || !VD->isLocalVarDeclOrParm()) in tryCaptureAsLocalVariable()
223 if (const auto *CE = dyn_cast<CXXConstructExpr>(BTE->getSubExpr())) in tryCaptureAsMemberVariable()
224 return tryCaptureAsMemberVariable(Result, B, CE->getArg(0)); in tryCaptureAsMemberVariable()
228 E = E->IgnoreImplicit(); in tryCaptureAsMemberVariable()
241 if (!ME->isLValue() || !isa<FieldDecl>(ME->getMemberDecl())) in tryCaptureAsMemberVariable()
244 if (isa<CXXThisExpr>(ME->getBase())) { in tryCaptureAsMemberVariable()
259 static llvm::Regex MatchPlaceholder("^_([0-9]+)$"); in buildBindArguments()
265 for (size_t I = 1, ArgCount = BindCall->getNumArgs(); I < ArgCount; ++I) { in buildBindArguments()
267 const Expr *E = BindCall->getArg(I); in buildBindArguments()
270 size_t ArgIndex = I - 1; in buildBindArguments()
272 --ArgIndex; in buildBindArguments()
278 if (!Callable.Decl || ArgIndex < Callable.Decl->getNumParams() || in buildBindArguments()
286 (DRE && MatchPlaceholder.match(DRE->getDecl()->getName(), &Matches))) { in buildBindArguments()
328 return -1; in findPositionOfPlaceholderUse()
331 static void addPlaceholderArgs(const LambdaProperties &LP, in addPlaceholderArgs() argument
335 ArrayRef<BindArgument> Args = LP.BindArguments; in addPlaceholderArgs()
345 MaxPlaceholderIt->PlaceHolderIndex == 0)) in addPlaceholderArgs()
348 size_t PlaceholderCount = MaxPlaceholderIt->PlaceHolderIndex; in addPlaceholderArgs()
356 if (ArgIndex != -1 && Args[ArgIndex].IsUsed) in addPlaceholderArgs()
401 for (const clang::CXXMethodDecl *Method : RecordDecl->methods()) { in findCandidateCallOperators()
402 OverloadedOperatorKind OOK = Method->getOverloadedOperator(); in findCandidateCallOperators()
407 if (Method->getNumParams() > NumArgs) in findCandidateCallOperators()
414 for (const clang::Decl *D : RecordDecl->decls()) { in findCandidateCallOperators()
418 const FunctionDecl *FD = FTD->getTemplatedDecl(); in findCandidateCallOperators()
420 OverloadedOperatorKind OOK = FD->getOverloadedOperator(); in findCandidateCallOperators()
424 if (FD->getNumParams() > NumArgs) in findCandidateCallOperators()
481 size_t NumArgs = BindCall->getNumArgs() - 1; in getCallMethodDecl()
482 return getCallOperator(Callee->getType()->getAsCXXRecordDecl(), NumArgs); in getCallMethodDecl()
487 return dyn_cast<FunctionDecl>(DRE->getDecl()); in getCallMethodDecl()
498 QualType QT = CallableExpr->getType(); in getCallableType()
499 if (QT->isMemberFunctionPointerType()) in getCallableType()
502 if (QT->isFunctionPointerType() || QT->isFunctionReferenceType() || in getCallableType()
503 QT->isFunctionType()) in getCallableType()
506 if (QT->isRecordType()) { in getCallableType()
507 const CXXRecordDecl *Decl = QT->getAsCXXRecordDecl(); in getCallableType()
525 if ((isa<CallExpr>(NoTemporaries)) || (CE && (CE->getNumArgs() > 0)) || in getCallableMaterialization()
526 (FC && (FC->getCastKind() == CK_ConstructorConversion))) in getCallableMaterialization()
527 // CE is something that looks like a call, with arguments - either in getCallableMaterialization()
535 if (isa<FunctionDecl>(DRE->getDecl())) in getCallableMaterialization()
537 if (isa<VarDecl>(DRE->getDecl())) in getCallableMaterialization()
548 LambdaProperties LP; in getLambdaProperties() local
551 const auto *Decl = dyn_cast<FunctionDecl>(Bind->getCalleeDecl()); in getLambdaProperties()
553 dyn_cast<NamespaceDecl>(Decl->getEnclosingNamespaceContext()); in getLambdaProperties()
554 while (NS->isInlineNamespace()) in getLambdaProperties()
555 NS = dyn_cast<NamespaceDecl>(NS->getDeclContext()); in getLambdaProperties()
556 LP.BindNamespace = NS->getName(); in getLambdaProperties()
558 LP.Callable.Type = getCallableType(Result); in getLambdaProperties()
559 LP.Callable.Materialization = getCallableMaterialization(Result); in getLambdaProperties()
560 LP.Callable.Decl = in getLambdaProperties()
561 getCallMethodDecl(Result, LP.Callable.Type, LP.Callable.Materialization); in getLambdaProperties()
562 LP.Callable.SourceTokens = getSourceTextForExpr(Result, CalleeExpr); in getLambdaProperties()
563 if (LP.Callable.Materialization == CMK_VariableRef) { in getLambdaProperties()
564 LP.Callable.CE = CE_Var; in getLambdaProperties()
565 LP.Callable.CM = CM_ByValue; in getLambdaProperties()
566 LP.Callable.UsageIdentifier = in getLambdaProperties()
568 LP.Callable.CaptureIdentifier = std::string( in getLambdaProperties()
570 } else if (LP.Callable.Materialization == CMK_CallExpression) { in getLambdaProperties()
571 LP.Callable.CE = CE_InitExpression; in getLambdaProperties()
572 LP.Callable.CM = CM_ByValue; in getLambdaProperties()
573 LP.Callable.UsageIdentifier = "Func"; in getLambdaProperties()
574 LP.Callable.CaptureIdentifier = "Func"; in getLambdaProperties()
575 LP.Callable.CaptureInitializer = getSourceTextForExpr(Result, CalleeExpr); in getLambdaProperties()
578 LP.BindArguments = buildBindArguments(Result, LP.Callable); in getLambdaProperties()
580 LP.IsFixitSupported = isFixitSupported(LP.Callable, LP.BindArguments); in getLambdaProperties()
582 return LP; in getLambdaProperties()
607 static void emitCaptureList(const LambdaProperties &LP, in emitCaptureList() argument
614 CaptureSet, "", LP.Callable.CM, LP.Callable.CE, in emitCaptureList()
615 LP.Callable.CaptureIdentifier, LP.Callable.CaptureInitializer, Stream); in emitCaptureList()
617 for (const BindArgument &B : LP.BindArguments) { in emitCaptureList()
646 Finder->addMatcher( in registerMatchers()
660 LambdaProperties LP = getLambdaProperties(Result); in check() local
662 diag(MatchedDecl->getBeginLoc(), in check()
663 formatv("prefer a lambda to {0}::bind", LP.BindNamespace).str()); in check()
664 if (!LP.IsFixitSupported) in check()
673 emitCaptureList(LP, Result, Stream); in check()
676 ArrayRef<BindArgument> FunctionCallArgs = makeArrayRef(LP.BindArguments); in check()
678 addPlaceholderArgs(LP, Stream, PermissiveParameterList); in check()
680 if (LP.Callable.Type == CT_Function) { in check()
681 StringRef SourceTokens = LP.Callable.SourceTokens; in check()
684 } else if (LP.Callable.Type == CT_MemberFunction) { in check()
685 const auto *MethodDecl = dyn_cast<CXXMethodDecl>(LP.Callable.Decl); in check()
691 Stream << "->"; in check()
694 Stream << MethodDecl->getName(); in check()
697 switch (LP.Callable.CE) { in check()
699 if (LP.Callable.UsageIdentifier != LP.Callable.CaptureIdentifier) { in check()
700 Stream << "(" << LP.Callable.UsageIdentifier << ")"; in check()
705 Stream << LP.Callable.UsageIdentifier; in check()
714 addFunctionCallArgs(getForwardedArgumentList(LP), Stream); in check()
717 Diag << FixItHint::CreateReplacement(MatchedDecl->getSourceRange(), in check()