void PassByValueCheck::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; Finder->addMatcher( cxxConstructorDecl( forEachConstructorInitializer( cxxCtorInitializer( // Clang builds a CXXConstructExpr only whin it knows which // constructor will be called. In dependent contexts a // ParenListExpr is generated instead of a CXXConstructExpr, // filtering out templates automatically for us. withInitializer(cxxConstructExpr( has(ignoringParenImpCasts(declRefExpr(to( parmVarDecl( hasType(qualType( // Match only const-ref or a non-const value // parameters. Rvalues and const-values // shouldn't be modified. anyOf(constRefType(), nonConstValueType())))) .bind("Param"))))), hasDeclaration(cxxConstructorDecl( isCopyConstructor(), unless(isDeleted()), hasDeclContext( cxxRecordDecl(isMoveConstructible()))))))) .bind("Initializer"))) .bind("Ctor"), this); }
void RedundantMemberInitCheck::registerMatchers(MatchFinder *Finder) { auto Construct = cxxConstructExpr( hasDeclaration(cxxConstructorDecl(hasParent( cxxRecordDecl(unless(isTriviallyDefaultConstructible())))))) .bind("construct"); Finder->addMatcher( cxxConstructorDecl( unless(isDelegatingConstructor()), ofClass(unless( anyOf(isUnion(), ast_matchers::isTemplateInstantiation()))), forEachConstructorInitializer( cxxCtorInitializer(isWritten(), withInitializer(ignoringImplicit(Construct)), unless(forField(hasType(isConstQualified())))) .bind("init"))), this); }