MakeSharedCheck::SmartPtrTypeMatcher MakeSharedCheck::getSmartPointerTypeMatcher() const { return qualType(hasDeclaration(classTemplateSpecializationDecl( matchesName("::std::shared_ptr"), templateArgumentCountIs(1), hasTemplateArgument( 0, templateArgument(refersToType(qualType().bind(PointerType))))))); }
void InefficientAlgorithmCheck::registerMatchers(MatchFinder *Finder) { // Only register the matchers for C++; the functionality currently does not // provide any benefit to other languages, despite being benign. if (!getLangOpts().CPlusPlus) return; const std::string Algorithms = "^::std::(find|count|equal_range|lower_bound|upper_bound)$"; const auto ContainerMatcher = classTemplateSpecializationDecl( matchesName("^::std::(unordered_)?(multi)?(set|map)$")); const auto Matcher = callExpr( callee(functionDecl(matchesName(Algorithms))), hasArgument( 0, constructExpr(has(memberCallExpr( callee(methodDecl(hasName("begin"))), on(declRefExpr( hasDeclaration(decl().bind("IneffContObj")), anyOf(hasType(ContainerMatcher.bind("IneffCont")), hasType(pointsTo( ContainerMatcher.bind("IneffContPtr"))))) .bind("IneffContExpr")))))), hasArgument(1, constructExpr(has(memberCallExpr( callee(methodDecl(hasName("end"))), on(declRefExpr(hasDeclaration( equalsBoundNode("IneffContObj")))))))), hasArgument(2, expr().bind("AlgParam")), unless(isInTemplateInstantiation())) .bind("IneffAlg"); Finder->addMatcher(Matcher, this); }
void NonMemMovableTemplateArgChecker::registerMatchers(MatchFinder* AstMatcher) { // Handle non-mem-movable template specializations AstMatcher->addMatcher( classTemplateSpecializationDecl( allOf(needsMemMovableTemplateArg(), hasAnyTemplateArgument(refersToType(isNonMemMovable())))) .bind("specialization"), this); }
void StringIntegerAssignmentCheck::registerMatchers(MatchFinder *Finder) { if (!getLangOpts().CPlusPlus) return; Finder->addMatcher( cxxOperatorCallExpr( anyOf(hasOverloadedOperatorName("="), hasOverloadedOperatorName("+=")), callee(cxxMethodDecl(ofClass(classTemplateSpecializationDecl( hasName("::std::basic_string"), hasTemplateArgument(0, refersToType(qualType().bind("type"))))))), hasArgument(1, ignoringImpCasts(expr(hasType(isInteger()), unless(hasType(isAnyCharacter()))) .bind("expr"))), unless(isInTemplateInstantiation())), this); }
void UseToStringCheck::registerMatchers(MatchFinder *Finder) { if (!getLangOpts().CPlusPlus) return; Finder->addMatcher( callExpr( hasDeclaration(functionDecl( returns(hasDeclaration(classTemplateSpecializationDecl( hasName("std::basic_string"), hasTemplateArgument(0, templateArgument().bind("char_type"))))), hasName("boost::lexical_cast"), hasParameter(0, hasType(qualType(has(substTemplateTypeParmType( isStrictlyInteger()))))))), argumentCountIs(1), unless(isInTemplateInstantiation())) .bind("to_string"), this); }
void UniqueptrDeleteReleaseCheck::registerMatchers(MatchFinder *Finder) { auto IsSusbstituted = qualType(anyOf( substTemplateTypeParmType(), hasDescendant(substTemplateTypeParmType()))); auto UniquePtrWithDefaultDelete = classTemplateSpecializationDecl( hasName("std::unique_ptr"), hasTemplateArgument(1, refersToType(qualType(hasDeclaration(cxxRecordDecl( hasName("std::default_delete"))))))); Finder->addMatcher( cxxDeleteExpr(has(ignoringParenImpCasts(cxxMemberCallExpr( on(expr(hasType(UniquePtrWithDefaultDelete), unless(hasType(IsSusbstituted))) .bind("uptr")), callee(cxxMethodDecl(hasName("release"))))))) .bind("delete"), this); }