Refactors AST matching code to use the new AST matcher names. This patch correlates to r247885 which performs the AST matcher rename in Clang.

llvm-svn: 247886
This commit is contained in:
Aaron Ballman 2015-09-17 13:31:25 +00:00
parent 512fb64765
commit b9ea09c445
31 changed files with 207 additions and 187 deletions

View File

@ -22,8 +22,8 @@ using namespace clang;
const char *MethodId = "method"; const char *MethodId = "method";
DeclarationMatcher makeCandidateForOverrideAttrMatcher() { DeclarationMatcher makeCandidateForOverrideAttrMatcher() {
return methodDecl(hasParent(recordDecl()), return cxxMethodDecl(hasParent(recordDecl()),
isOverride(), isOverride(),
unless(destructorDecl())).bind(MethodId); unless(cxxDestructorDecl())).bind(MethodId);
} }

View File

@ -112,10 +112,10 @@ StatementMatcher makeArrayLoopMatcher() {
/// - If the end iterator variable 'g' is defined, it is the same as 'f' /// - If the end iterator variable 'g' is defined, it is the same as 'f'
StatementMatcher makeIteratorLoopMatcher() { StatementMatcher makeIteratorLoopMatcher() {
StatementMatcher BeginCallMatcher = StatementMatcher BeginCallMatcher =
memberCallExpr( cxxMemberCallExpr(
argumentCountIs(0), argumentCountIs(0),
callee( callee(
methodDecl(hasName("begin")) cxxMethodDecl(hasName("begin"))
) )
).bind(BeginCallName); ).bind(BeginCallName);
@ -133,8 +133,8 @@ StatementMatcher makeIteratorLoopMatcher() {
DeclarationMatcher EndDeclMatcher = DeclarationMatcher EndDeclMatcher =
varDecl(hasInitializer(anything())).bind(EndVarName); varDecl(hasInitializer(anything())).bind(EndVarName);
StatementMatcher EndCallMatcher = StatementMatcher EndCallMatcher = cxxMemberCallExpr(
memberCallExpr(argumentCountIs(0), callee(methodDecl(hasName("end")))); argumentCountIs(0), callee(cxxMethodDecl(hasName("end"))));
StatementMatcher IteratorBoundMatcher = StatementMatcher IteratorBoundMatcher =
expr(anyOf(ignoringParenImpCasts(declRefExpr(to( expr(anyOf(ignoringParenImpCasts(declRefExpr(to(
@ -148,7 +148,7 @@ StatementMatcher makeIteratorLoopMatcher() {
expr(ignoringParenImpCasts(declRefExpr(to( expr(ignoringParenImpCasts(declRefExpr(to(
varDecl().bind(ConditionVarName))))); varDecl().bind(ConditionVarName)))));
StatementMatcher OverloadedNEQMatcher = operatorCallExpr( StatementMatcher OverloadedNEQMatcher = cxxOperatorCallExpr(
hasOverloadedOperatorName("!="), hasOverloadedOperatorName("!="),
argumentCountIs(2), argumentCountIs(2),
hasArgument(0, IteratorComparisonMatcher), hasArgument(0, IteratorComparisonMatcher),
@ -159,7 +159,7 @@ StatementMatcher makeIteratorLoopMatcher() {
// reference then the return type is tagged with DerefByValueResultName. // reference then the return type is tagged with DerefByValueResultName.
internal::Matcher<VarDecl> TestDerefReturnsByValue = internal::Matcher<VarDecl> TestDerefReturnsByValue =
hasType( hasType(
recordDecl( cxxRecordDecl(
hasMethod( hasMethod(
allOf( allOf(
hasOverloadedOperatorName("*"), hasOverloadedOperatorName("*"),
@ -218,7 +218,7 @@ StatementMatcher makeIteratorLoopMatcher() {
)) ))
) )
), ),
operatorCallExpr( cxxOperatorCallExpr(
hasOverloadedOperatorName("++"), hasOverloadedOperatorName("++"),
hasArgument(0, hasArgument(0,
declRefExpr(to( declRefExpr(to(
@ -276,15 +276,15 @@ StatementMatcher makePseudoArrayLoopMatcher() {
qualType( qualType(
isConstQualified(), isConstQualified(),
hasDeclaration( hasDeclaration(
recordDecl( cxxRecordDecl(
hasMethod( hasMethod(
methodDecl( cxxMethodDecl(
hasName("begin"), hasName("begin"),
isConst() isConst()
) )
), ),
hasMethod( hasMethod(
methodDecl( cxxMethodDecl(
hasName("end"), hasName("end"),
isConst() isConst()
) )
@ -295,7 +295,7 @@ StatementMatcher makePseudoArrayLoopMatcher() {
qualType( qualType(
unless(isConstQualified()), unless(isConstQualified()),
hasDeclaration( hasDeclaration(
recordDecl( cxxRecordDecl(
hasMethod(hasName("begin")), hasMethod(hasName("begin")),
hasMethod(hasName("end")) hasMethod(hasName("end"))
) )
@ -304,12 +304,11 @@ StatementMatcher makePseudoArrayLoopMatcher() {
) )
); );
StatementMatcher SizeCallMatcher = StatementMatcher SizeCallMatcher = cxxMemberCallExpr(
memberCallExpr(argumentCountIs(0), argumentCountIs(0),
callee(methodDecl(anyOf(hasName("size"), callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
hasName("length")))), on(anyOf(hasType(pointsTo(RecordWithBeginEnd)),
on(anyOf(hasType(pointsTo(RecordWithBeginEnd)), hasType(RecordWithBeginEnd))));
hasType(RecordWithBeginEnd))));
StatementMatcher EndInitMatcher = StatementMatcher EndInitMatcher =
expr(anyOf( expr(anyOf(

View File

@ -59,13 +59,13 @@ static TypeMatcher nonConstValueType() {
} }
DeclarationMatcher makePassByValueCtorParamMatcher() { DeclarationMatcher makePassByValueCtorParamMatcher() {
return constructorDecl( return cxxConstructorDecl(
forEachConstructorInitializer(ctorInitializer( forEachConstructorInitializer(cxxCtorInitializer(
// Clang builds a CXXConstructExpr only when it knowns which // Clang builds a CXXConstructExpr only when it knowns which
// constructor will be called. In dependent contexts a ParenListExpr // constructor will be called. In dependent contexts a ParenListExpr
// is generated instead of a CXXConstructExpr, filtering out templates // is generated instead of a CXXConstructExpr, filtering out templates
// automatically for us. // automatically for us.
withInitializer(constructExpr( withInitializer(cxxConstructExpr(
has(declRefExpr(to( has(declRefExpr(to(
parmVarDecl(hasType(qualType( parmVarDecl(hasType(qualType(
// match only const-ref or a non-const value // match only const-ref or a non-const value
@ -73,9 +73,9 @@ DeclarationMatcher makePassByValueCtorParamMatcher() {
// shouldn't be modified. // shouldn't be modified.
anyOf(constRefType(), nonConstValueType())))) anyOf(constRefType(), nonConstValueType()))))
.bind(PassByValueParamId)))), .bind(PassByValueParamId)))),
hasDeclaration(constructorDecl( hasDeclaration(cxxConstructorDecl(
isCopyConstructor(), unless(isDeleted()), isCopyConstructor(), unless(isDeleted()),
hasDeclContext(recordDecl(isMoveConstructible()))))))) hasDeclContext(cxxRecordDecl(isMoveConstructible())))))))
.bind(PassByValueInitializerId))) .bind(PassByValueInitializerId)))
.bind(PassByValueCtorId); .bind(PassByValueCtorId);
} }

View File

@ -67,13 +67,13 @@ DeclarationMatcher makeAutoPtrUsingDeclMatcher() {
StatementMatcher makeTransferOwnershipExprMatcher() { StatementMatcher makeTransferOwnershipExprMatcher() {
StatementMatcher assignOperator = StatementMatcher assignOperator =
operatorCallExpr(allOf( cxxOperatorCallExpr(allOf(
hasOverloadedOperatorName("="), hasOverloadedOperatorName("="),
callee(methodDecl(ofClass(AutoPtrDecl))), callee(cxxMethodDecl(ofClass(AutoPtrDecl))),
hasArgument(1, MovableArgumentMatcher))); hasArgument(1, MovableArgumentMatcher)));
StatementMatcher copyCtor = StatementMatcher copyCtor =
constructExpr(allOf(hasType(AutoPtrType), cxxConstructExpr(allOf(hasType(AutoPtrType),
argumentCountIs(1), argumentCountIs(1),
hasArgument(0, MovableArgumentMatcher))); hasArgument(0, MovableArgumentMatcher)));

View File

@ -258,7 +258,7 @@ StatementMatcher makeDeclWithNewMatcher() {
unless(has(varDecl( unless(has(varDecl(
anyOf( anyOf(
unless(hasInitializer( unless(hasInitializer(
ignoringParenImpCasts(newExpr()) ignoringParenImpCasts(cxxNewExpr())
)), )),
// FIXME: TypeLoc information is not reliable where CV qualifiers are // FIXME: TypeLoc information is not reliable where CV qualifiers are
// concerned so these types can't be handled for now. // concerned so these types can't be handled for now.

View File

@ -23,8 +23,8 @@ void ExplicitConstructorCheck::registerMatchers(MatchFinder *Finder) {
// Only register the matchers for C++; the functionality currently does not // Only register the matchers for C++; the functionality currently does not
// provide any benefit to other languages, despite being benign. // provide any benefit to other languages, despite being benign.
if (getLangOpts().CPlusPlus) if (getLangOpts().CPlusPlus)
Finder->addMatcher(constructorDecl(unless(isInstantiated())).bind("ctor"), Finder->addMatcher(
this); cxxConstructorDecl(unless(isInstantiated())).bind("ctor"), this);
} }
// Looks for the token matching the predicate and returns the range of the found // Looks for the token matching the predicate and returns the range of the found

View File

@ -27,14 +27,15 @@ OverloadedUnaryAndCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
return; return;
// Match unary methods that overload operator&. // Match unary methods that overload operator&.
Finder->addMatcher(methodDecl(parameterCountIs(0), hasOverloadedOperatorName( Finder->addMatcher(
"&")).bind("overload"), cxxMethodDecl(parameterCountIs(0), hasOverloadedOperatorName("&"))
this); .bind("overload"),
this);
// Also match freestanding unary operator& overloads. Be careful not to match // Also match freestanding unary operator& overloads. Be careful not to match
// binary methods. // binary methods.
Finder->addMatcher( Finder->addMatcher(
functionDecl( functionDecl(
allOf(unless(methodDecl()), allOf(unless(cxxMethodDecl()),
functionDecl(parameterCountIs(1), functionDecl(parameterCountIs(1),
hasOverloadedOperatorName("&")).bind("overload"))), hasOverloadedOperatorName("&")).bind("overload"))),
this); this);

View File

@ -26,7 +26,7 @@ ArgumentCommentCheck::ArgumentCommentCheck(StringRef Name,
void ArgumentCommentCheck::registerMatchers(MatchFinder *Finder) { void ArgumentCommentCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher( Finder->addMatcher(
callExpr(unless(operatorCallExpr()), callExpr(unless(cxxOperatorCallExpr()),
// NewCallback's arguments relate to the pointed function, don't // NewCallback's arguments relate to the pointed function, don't
// check them against NewCallback's parameter names. // check them against NewCallback's parameter names.
// FIXME: Make this configurable. // FIXME: Make this configurable.
@ -34,7 +34,7 @@ void ArgumentCommentCheck::registerMatchers(MatchFinder *Finder) {
hasName("NewCallback"), hasName("NewPermanentCallback")))))) hasName("NewCallback"), hasName("NewPermanentCallback"))))))
.bind("expr"), .bind("expr"),
this); this);
Finder->addMatcher(constructExpr().bind("expr"), this); Finder->addMatcher(cxxConstructExpr().bind("expr"), this);
} }
std::vector<std::pair<SourceLocation, StringRef>> std::vector<std::pair<SourceLocation, StringRef>>

View File

@ -24,20 +24,21 @@ void AssignOperatorSignatureCheck::registerMatchers(
if (!getLangOpts().CPlusPlus) if (!getLangOpts().CPlusPlus)
return; return;
const auto HasGoodReturnType = methodDecl(returns(lValueReferenceType(pointee( const auto HasGoodReturnType = cxxMethodDecl(returns(
unless(isConstQualified()), hasDeclaration(equalsBoundNode("class")))))); lValueReferenceType(pointee(unless(isConstQualified()),
hasDeclaration(equalsBoundNode("class"))))));
const auto IsSelf = qualType( const auto IsSelf = qualType(
anyOf(hasDeclaration(equalsBoundNode("class")), anyOf(hasDeclaration(equalsBoundNode("class")),
referenceType(pointee(hasDeclaration(equalsBoundNode("class")))))); referenceType(pointee(hasDeclaration(equalsBoundNode("class"))))));
const auto IsSelfAssign = const auto IsSelfAssign =
methodDecl(unless(anyOf(isDeleted(), isPrivate(), isImplicit())), cxxMethodDecl(unless(anyOf(isDeleted(), isPrivate(), isImplicit())),
hasName("operator="), ofClass(recordDecl().bind("class")), hasName("operator="), ofClass(recordDecl().bind("class")),
hasParameter(0, parmVarDecl(hasType(IsSelf)))) hasParameter(0, parmVarDecl(hasType(IsSelf))))
.bind("method"); .bind("method");
Finder->addMatcher( Finder->addMatcher(
methodDecl(IsSelfAssign, unless(HasGoodReturnType)).bind("ReturnType"), cxxMethodDecl(IsSelfAssign, unless(HasGoodReturnType)).bind("ReturnType"),
this); this);
const auto BadSelf = referenceType( const auto BadSelf = referenceType(
@ -45,11 +46,13 @@ void AssignOperatorSignatureCheck::registerMatchers(
rValueReferenceType(pointee(isConstQualified())))); rValueReferenceType(pointee(isConstQualified()))));
Finder->addMatcher( Finder->addMatcher(
methodDecl(IsSelfAssign, hasParameter(0, parmVarDecl(hasType(BadSelf)))) cxxMethodDecl(IsSelfAssign,
hasParameter(0, parmVarDecl(hasType(BadSelf))))
.bind("ArgumentType"), .bind("ArgumentType"),
this); this);
Finder->addMatcher(methodDecl(IsSelfAssign, isConst()).bind("Const"), this); Finder->addMatcher(cxxMethodDecl(IsSelfAssign, isConst()).bind("Const"),
this);
} }

View File

@ -63,7 +63,7 @@ void BoolPointerImplicitConversionCheck::check(
// bool. // bool.
!match(findAll(callExpr(hasAnyArgument(DeclRef))), *If, *Result.Context) !match(findAll(callExpr(hasAnyArgument(DeclRef))), *If, *Result.Context)
.empty() || .empty() ||
!match(findAll(deleteExpr(has(expr(DeclRef)))), *If, *Result.Context) !match(findAll(cxxDeleteExpr(has(expr(DeclRef)))), *If, *Result.Context)
.empty()) .empty())
return; return;

View File

@ -25,15 +25,15 @@ void InaccurateEraseCheck::registerMatchers(MatchFinder *Finder) {
return; return;
const auto CheckForEndCall = hasArgument( const auto CheckForEndCall = hasArgument(
1, 1, anyOf(cxxConstructExpr(
anyOf(constructExpr(has(memberCallExpr(callee(methodDecl(hasName("end")))) has(cxxMemberCallExpr(callee(cxxMethodDecl(hasName("end"))))
.bind("InaccEndCall"))), .bind("InaccEndCall"))),
anything())); anything()));
Finder->addMatcher( Finder->addMatcher(
memberCallExpr( cxxMemberCallExpr(
on(hasType(namedDecl(matchesName("^::std::")))), on(hasType(namedDecl(matchesName("^::std::")))),
callee(methodDecl(hasName("erase"))), argumentCountIs(1), callee(cxxMethodDecl(hasName("erase"))), argumentCountIs(1),
hasArgument(0, has(callExpr(callee(functionDecl(matchesName( hasArgument(0, has(callExpr(callee(functionDecl(matchesName(
"^::std::(remove(_if)?|unique)$"))), "^::std::(remove(_if)?|unique)$"))),
CheckForEndCall) CheckForEndCall)

View File

@ -41,16 +41,16 @@ void InefficientAlgorithmCheck::registerMatchers(MatchFinder *Finder) {
callExpr( callExpr(
callee(functionDecl(matchesName(Algorithms))), callee(functionDecl(matchesName(Algorithms))),
hasArgument( hasArgument(
0, constructExpr(has(memberCallExpr( 0, cxxConstructExpr(has(cxxMemberCallExpr(
callee(methodDecl(hasName("begin"))), callee(cxxMethodDecl(hasName("begin"))),
on(declRefExpr( on(declRefExpr(
hasDeclaration(decl().bind("IneffContObj")), hasDeclaration(decl().bind("IneffContObj")),
anyOf(hasType(ContainerMatcher.bind("IneffCont")), anyOf(hasType(ContainerMatcher.bind("IneffCont")),
hasType(pointsTo( hasType(pointsTo(
ContainerMatcher.bind("IneffContPtr"))))) ContainerMatcher.bind("IneffContPtr")))))
.bind("IneffContExpr")))))), .bind("IneffContExpr")))))),
hasArgument(1, constructExpr(has(memberCallExpr( hasArgument(1, cxxConstructExpr(has(cxxMemberCallExpr(
callee(methodDecl(hasName("end"))), callee(cxxMethodDecl(hasName("end"))),
on(declRefExpr(hasDeclaration( on(declRefExpr(hasDeclaration(
equalsBoundNode("IneffContObj")))))))), equalsBoundNode("IneffContObj")))))))),
hasArgument(2, expr().bind("AlgParam")), hasArgument(2, expr().bind("AlgParam")),

View File

@ -23,14 +23,16 @@ void MoveConstructorInitCheck::registerMatchers(MatchFinder *Finder) {
return; return;
Finder->addMatcher( Finder->addMatcher(
constructorDecl(unless(isImplicit()), allOf( cxxConstructorDecl(
isMoveConstructor(), unless(isImplicit()),
hasAnyConstructorInitializer( allOf(isMoveConstructor(),
ctorInitializer(withInitializer(constructExpr(hasDeclaration( hasAnyConstructorInitializer(
constructorDecl(isCopyConstructor()).bind("ctor") cxxCtorInitializer(
)))).bind("init") withInitializer(cxxConstructExpr(hasDeclaration(
) cxxConstructorDecl(isCopyConstructor())
)), this); .bind("ctor")))))
.bind("init")))),
this);
} }
void MoveConstructorInitCheck::check(const MatchFinder::MatchResult &Result) { void MoveConstructorInitCheck::check(const MatchFinder::MatchResult &Result) {

View File

@ -23,8 +23,8 @@ void NoexceptMoveConstructorCheck::registerMatchers(MatchFinder *Finder) {
return; return;
Finder->addMatcher( Finder->addMatcher(
methodDecl(anyOf(constructorDecl(), hasOverloadedOperatorName("=")), cxxMethodDecl(anyOf(cxxConstructorDecl(), hasOverloadedOperatorName("=")),
unless(isImplicit()), unless(isDeleted())) unless(isImplicit()), unless(isDeleted()))
.bind("decl"), .bind("decl"),
this); this);
} }

View File

@ -19,11 +19,12 @@ namespace tidy {
void SizeofContainerCheck::registerMatchers(MatchFinder *Finder) { void SizeofContainerCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher( Finder->addMatcher(
expr(unless(isInTemplateInstantiation()), expr(unless(isInTemplateInstantiation()),
expr(sizeOfExpr(has(expr(hasType(hasCanonicalType(hasDeclaration( expr(sizeOfExpr(has(
recordDecl(matchesName("^(::std::|::string)"), expr(hasType(hasCanonicalType(hasDeclaration(cxxRecordDecl(
unless(matchesName("^::std::(bitset|array)$")), matchesName("^(::std::|::string)"),
hasMethod(methodDecl(hasName("size"), isPublic(), unless(matchesName("^::std::(bitset|array)$")),
isConst())))))))))) hasMethod(cxxMethodDecl(hasName("size"), isPublic(),
isConst()))))))))))
.bind("sizeof"), .bind("sizeof"),
// Ignore ARRAYSIZE(<array of containers>) pattern. // Ignore ARRAYSIZE(<array of containers>) pattern.
unless(hasAncestor(binaryOperator( unless(hasAncestor(binaryOperator(

View File

@ -33,8 +33,8 @@ void StaticAssertCheck::registerMatchers(MatchFinder *Finder) {
return; return;
auto IsAlwaysFalse = expr(ignoringParenImpCasts( auto IsAlwaysFalse = expr(ignoringParenImpCasts(
expr(anyOf(boolLiteral(equals(false)), integerLiteral(equals(0)), expr(anyOf(cxxBoolLiteral(equals(false)), integerLiteral(equals(0)),
nullPtrLiteralExpr(), gnuNullExpr())) cxxNullPtrLiteralExpr(), gnuNullExpr()))
.bind("isAlwaysFalse"))); .bind("isAlwaysFalse")));
auto IsAlwaysFalseWithCast = ignoringParenImpCasts(anyOf( auto IsAlwaysFalseWithCast = ignoringParenImpCasts(anyOf(
IsAlwaysFalse, cStyleCastExpr(has(IsAlwaysFalse)).bind("castExpr"))); IsAlwaysFalse, cStyleCastExpr(has(IsAlwaysFalse)).bind("castExpr")));

View File

@ -63,10 +63,11 @@ void UndelegatedConstructorCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher( Finder->addMatcher(
compoundStmt( compoundStmt(
hasParent(constructorDecl(ofClass(recordDecl().bind("parent")))), hasParent(
cxxConstructorDecl(ofClass(cxxRecordDecl().bind("parent")))),
forEach(ignoringTemporaryExpr( forEach(ignoringTemporaryExpr(
constructExpr(hasDeclaration(constructorDecl(ofClass( cxxConstructExpr(hasDeclaration(cxxConstructorDecl(ofClass(
recordDecl(baseOfBoundNode("parent")))))) cxxRecordDecl(baseOfBoundNode("parent"))))))
.bind("construct"))), .bind("construct"))),
unless(isInTemplateInstantiation())), unless(isInTemplateInstantiation())),
this); this);

View File

@ -24,18 +24,19 @@ void UniqueptrResetReleaseCheck::registerMatchers(MatchFinder *Finder) {
return; return;
Finder->addMatcher( Finder->addMatcher(
memberCallExpr( cxxMemberCallExpr(
on(expr().bind("left")), callee(memberExpr().bind("reset_member")), on(expr().bind("left")), callee(memberExpr().bind("reset_member")),
callee(methodDecl(hasName("reset"), callee(
ofClass(recordDecl(hasName("::std::unique_ptr"), cxxMethodDecl(hasName("reset"),
decl().bind("left_class"))))), ofClass(cxxRecordDecl(hasName("::std::unique_ptr"),
has(memberCallExpr( decl().bind("left_class"))))),
has(cxxMemberCallExpr(
on(expr().bind("right")), on(expr().bind("right")),
callee(memberExpr().bind("release_member")), callee(memberExpr().bind("release_member")),
callee(methodDecl( callee(cxxMethodDecl(
hasName("release"), hasName("release"),
ofClass(recordDecl(hasName("::std::unique_ptr"), ofClass(cxxRecordDecl(hasName("::std::unique_ptr"),
decl().bind("right_class")))))))) decl().bind("right_class"))))))))
.bind("reset_call"), .bind("reset_call"),
this); this);
} }

View File

@ -33,13 +33,13 @@ void UnusedRAIICheck::registerMatchers(MatchFinder *Finder) {
// Look for temporaries that are constructed in-place and immediately // Look for temporaries that are constructed in-place and immediately
// destroyed. Look for temporaries created by a functional cast but not for // destroyed. Look for temporaries created by a functional cast but not for
// those returned from a call. // those returned from a call.
auto BindTemp = bindTemporaryExpr(unless(has(callExpr()))).bind("temp"); auto BindTemp = cxxBindTemporaryExpr(unless(has(callExpr()))).bind("temp");
Finder->addMatcher( Finder->addMatcher(
exprWithCleanups( exprWithCleanups(
unless(isInTemplateInstantiation()), unless(isInTemplateInstantiation()),
hasParent(compoundStmt().bind("compound")), hasParent(compoundStmt().bind("compound")),
hasType(recordDecl(hasNonTrivialDestructor())), hasType(cxxRecordDecl(hasNonTrivialDestructor())),
anyOf(has(BindTemp), has(functionalCastExpr(has(BindTemp))))) anyOf(has(BindTemp), has(cxxFunctionalCastExpr(has(BindTemp)))))
.bind("expr"), .bind("expr"),
this); this);
} }

View File

@ -112,7 +112,8 @@ StatementMatcher makeArrayLoopMatcher() {
/// - If the end iterator variable 'g' is defined, it is the same as 'f'. /// - If the end iterator variable 'g' is defined, it is the same as 'f'.
StatementMatcher makeIteratorLoopMatcher() { StatementMatcher makeIteratorLoopMatcher() {
StatementMatcher BeginCallMatcher = StatementMatcher BeginCallMatcher =
memberCallExpr(argumentCountIs(0), callee(methodDecl(hasName("begin")))) cxxMemberCallExpr(argumentCountIs(0),
callee(cxxMethodDecl(hasName("begin"))))
.bind(BeginCallName); .bind(BeginCallName);
DeclarationMatcher InitDeclMatcher = DeclarationMatcher InitDeclMatcher =
@ -125,8 +126,8 @@ StatementMatcher makeIteratorLoopMatcher() {
DeclarationMatcher EndDeclMatcher = DeclarationMatcher EndDeclMatcher =
varDecl(hasInitializer(anything())).bind(EndVarName); varDecl(hasInitializer(anything())).bind(EndVarName);
StatementMatcher EndCallMatcher = StatementMatcher EndCallMatcher = cxxMemberCallExpr(
memberCallExpr(argumentCountIs(0), callee(methodDecl(hasName("end")))); argumentCountIs(0), callee(cxxMethodDecl(hasName("end"))));
StatementMatcher IteratorBoundMatcher = StatementMatcher IteratorBoundMatcher =
expr(anyOf(ignoringParenImpCasts( expr(anyOf(ignoringParenImpCasts(
@ -139,15 +140,15 @@ StatementMatcher makeIteratorLoopMatcher() {
ignoringParenImpCasts(declRefExpr(to(varDecl().bind(ConditionVarName))))); ignoringParenImpCasts(declRefExpr(to(varDecl().bind(ConditionVarName)))));
StatementMatcher OverloadedNEQMatcher = StatementMatcher OverloadedNEQMatcher =
operatorCallExpr(hasOverloadedOperatorName("!="), argumentCountIs(2), cxxOperatorCallExpr(hasOverloadedOperatorName("!="), argumentCountIs(2),
hasArgument(0, IteratorComparisonMatcher), hasArgument(0, IteratorComparisonMatcher),
hasArgument(1, IteratorBoundMatcher)); hasArgument(1, IteratorBoundMatcher));
// This matcher tests that a declaration is a CXXRecordDecl that has an // This matcher tests that a declaration is a CXXRecordDecl that has an
// overloaded operator*(). If the operator*() returns by value instead of by // overloaded operator*(). If the operator*() returns by value instead of by
// reference then the return type is tagged with DerefByValueResultName. // reference then the return type is tagged with DerefByValueResultName.
internal::Matcher<VarDecl> TestDerefReturnsByValue = internal::Matcher<VarDecl> TestDerefReturnsByValue =
hasType(recordDecl(hasMethod(allOf( hasType(cxxRecordDecl(hasMethod(allOf(
hasOverloadedOperatorName("*"), hasOverloadedOperatorName("*"),
anyOf( anyOf(
// Tag the return type if it's by value. // Tag the return type if it's by value.
@ -178,7 +179,7 @@ StatementMatcher makeIteratorLoopMatcher() {
hasUnaryOperand(declRefExpr( hasUnaryOperand(declRefExpr(
to(varDecl(hasType(pointsTo(AnyType))) to(varDecl(hasType(pointsTo(AnyType)))
.bind(IncrementVarName))))), .bind(IncrementVarName))))),
operatorCallExpr( cxxOperatorCallExpr(
hasOverloadedOperatorName("++"), hasOverloadedOperatorName("++"),
hasArgument( hasArgument(
0, declRefExpr(to(varDecl(TestDerefReturnsByValue) 0, declRefExpr(to(varDecl(TestDerefReturnsByValue)
@ -229,20 +230,20 @@ StatementMatcher makePseudoArrayLoopMatcher() {
// are also allowed. // are also allowed.
TypeMatcher RecordWithBeginEnd = qualType( TypeMatcher RecordWithBeginEnd = qualType(
anyOf(qualType(isConstQualified(), anyOf(qualType(isConstQualified(),
hasDeclaration(recordDecl( hasDeclaration(cxxRecordDecl(
hasMethod(methodDecl(hasName("begin"), isConst())), hasMethod(cxxMethodDecl(hasName("begin"), isConst())),
hasMethod(methodDecl(hasName("end"), hasMethod(cxxMethodDecl(hasName("end"),
isConst())))) // hasDeclaration isConst())))) // hasDeclaration
), // qualType ), // qualType
qualType(unless(isConstQualified()), qualType(unless(isConstQualified()),
hasDeclaration( hasDeclaration(
recordDecl(hasMethod(hasName("begin")), cxxRecordDecl(hasMethod(hasName("begin")),
hasMethod(hasName("end"))))) // qualType hasMethod(hasName("end"))))) // qualType
)); ));
StatementMatcher SizeCallMatcher = memberCallExpr( StatementMatcher SizeCallMatcher = cxxMemberCallExpr(
argumentCountIs(0), argumentCountIs(0),
callee(methodDecl(anyOf(hasName("size"), hasName("length")))), callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
on(anyOf(hasType(pointsTo(RecordWithBeginEnd)), on(anyOf(hasType(pointsTo(RecordWithBeginEnd)),
hasType(RecordWithBeginEnd)))); hasType(RecordWithBeginEnd))));

View File

@ -131,14 +131,14 @@ void PassByValueCheck::registerMatchers(MatchFinder *Finder) {
// provide any benefit to other languages, despite being benign. // provide any benefit to other languages, despite being benign.
if (getLangOpts().CPlusPlus) { if (getLangOpts().CPlusPlus) {
Finder->addMatcher( Finder->addMatcher(
constructorDecl( cxxConstructorDecl(
forEachConstructorInitializer( forEachConstructorInitializer(
ctorInitializer( cxxCtorInitializer(
// Clang builds a CXXConstructExpr only whin it knows which // Clang builds a CXXConstructExpr only whin it knows which
// constructor will be called. In dependent contexts a // constructor will be called. In dependent contexts a
// ParenListExpr is generated instead of a CXXConstructExpr, // ParenListExpr is generated instead of a CXXConstructExpr,
// filtering out templates automatically for us. // filtering out templates automatically for us.
withInitializer(constructExpr( withInitializer(cxxConstructExpr(
has(declRefExpr(to( has(declRefExpr(to(
parmVarDecl( parmVarDecl(
hasType(qualType( hasType(qualType(
@ -148,10 +148,10 @@ void PassByValueCheck::registerMatchers(MatchFinder *Finder) {
anyOf(constRefType(), anyOf(constRefType(),
nonConstValueType())))) nonConstValueType()))))
.bind("Param")))), .bind("Param")))),
hasDeclaration(constructorDecl( hasDeclaration(cxxConstructorDecl(
isCopyConstructor(), unless(isDeleted()), isCopyConstructor(), unless(isDeleted()),
hasDeclContext( hasDeclContext(
recordDecl(isMoveConstructible()))))))) cxxRecordDecl(isMoveConstructible())))))))
.bind("Initializer"))) .bind("Initializer")))
.bind("Ctor"), .bind("Ctor"),
this); this);

View File

@ -130,11 +130,12 @@ DeclarationMatcher makeAutoPtrUsingDeclMatcher() {
/// ~~~~^ /// ~~~~^
/// \endcode /// \endcode
StatementMatcher makeTransferOwnershipExprMatcher() { StatementMatcher makeTransferOwnershipExprMatcher() {
return anyOf(operatorCallExpr(allOf(hasOverloadedOperatorName("="), return anyOf(
callee(methodDecl(ofClass(AutoPtrDecl))), cxxOperatorCallExpr(allOf(hasOverloadedOperatorName("="),
hasArgument(1, MovableArgumentMatcher))), callee(cxxMethodDecl(ofClass(AutoPtrDecl))),
constructExpr(allOf(hasType(AutoPtrType), argumentCountIs(1), hasArgument(1, MovableArgumentMatcher))),
hasArgument(0, MovableArgumentMatcher)))); cxxConstructExpr(allOf(hasType(AutoPtrType), argumentCountIs(1),
hasArgument(0, MovableArgumentMatcher))));
} }
/// \brief Locates the \c auto_ptr token when it is referred by a \c TypeLoc. /// \brief Locates the \c auto_ptr token when it is referred by a \c TypeLoc.

View File

@ -42,7 +42,7 @@ void ShrinkToFitCheck::registerMatchers(MatchFinder *Finder) {
memberExpr(member(valueDecl().bind("ContainerDecl"))); memberExpr(member(valueDecl().bind("ContainerDecl")));
const auto ShrinkableAsDecl = const auto ShrinkableAsDecl =
declRefExpr(hasDeclaration(valueDecl().bind("ContainerDecl"))); declRefExpr(hasDeclaration(valueDecl().bind("ContainerDecl")));
const auto CopyCtorCall = constructExpr( const auto CopyCtorCall = cxxConstructExpr(
hasArgument(0, anyOf(ShrinkableAsMember, ShrinkableAsDecl, hasArgument(0, anyOf(ShrinkableAsMember, ShrinkableAsDecl,
unaryOperator(has(ShrinkableAsMember)), unaryOperator(has(ShrinkableAsMember)),
unaryOperator(has(ShrinkableAsDecl))))); unaryOperator(has(ShrinkableAsDecl)))));
@ -54,11 +54,11 @@ void ShrinkToFitCheck::registerMatchers(MatchFinder *Finder) {
has(declRefExpr(hasDeclaration(equalsBoundNode("ContainerDecl"))))))); has(declRefExpr(hasDeclaration(equalsBoundNode("ContainerDecl")))))));
Finder->addMatcher( Finder->addMatcher(
memberCallExpr(on(hasType(namedDecl(stlShrinkableContainer()))), cxxMemberCallExpr(on(hasType(namedDecl(stlShrinkableContainer()))),
callee(methodDecl(hasName("swap"))), callee(cxxMethodDecl(hasName("swap"))),
has(memberExpr(hasDescendant(CopyCtorCall))), has(memberExpr(hasDescendant(CopyCtorCall))),
hasArgument(0, SwapParam.bind("ContainerToShrink")), hasArgument(0, SwapParam.bind("ContainerToShrink")),
unless(isInTemplateInstantiation())) unless(isInTemplateInstantiation()))
.bind("CopyAndSwapTrick"), .bind("CopyAndSwapTrick"),
this); this);
} }

View File

@ -218,20 +218,21 @@ StatementMatcher makeIteratorDeclMatcher() {
} }
StatementMatcher makeDeclWithNewMatcher() { StatementMatcher makeDeclWithNewMatcher() {
return declStmt(has(varDecl()), return declStmt(
unless(has(varDecl(anyOf( has(varDecl()),
unless(hasInitializer(ignoringParenImpCasts(newExpr()))), unless(has(varDecl(anyOf(
// FIXME: TypeLoc information is not reliable where CV unless(hasInitializer(ignoringParenImpCasts(cxxNewExpr()))),
// qualifiers are concerned so these types can't be // FIXME: TypeLoc information is not reliable where CV
// handled for now. // qualifiers are concerned so these types can't be
hasType(pointerType( // handled for now.
pointee(hasCanonicalType(hasLocalQualifiers())))), hasType(pointerType(
pointee(hasCanonicalType(hasLocalQualifiers())))),
// FIXME: Handle function pointers. For now we ignore them // FIXME: Handle function pointers. For now we ignore them
// because the replacement replaces the entire type // because the replacement replaces the entire type
// specifier source range which includes the identifier. // specifier source range which includes the identifier.
hasType(pointsTo( hasType(pointsTo(
pointsTo(parenType(innerType(functionType())))))))))) pointsTo(parenType(innerType(functionType()))))))))))
.bind(DeclWithNewId); .bind(DeclWithNewId);
} }

View File

@ -21,7 +21,7 @@ namespace modernize {
void UseOverrideCheck::registerMatchers(MatchFinder *Finder) { void UseOverrideCheck::registerMatchers(MatchFinder *Finder) {
// Only register the matcher for C++11. // Only register the matcher for C++11.
if (getLangOpts().CPlusPlus11) if (getLangOpts().CPlusPlus11)
Finder->addMatcher(methodDecl(isOverride()).bind("method"), this); Finder->addMatcher(cxxMethodDecl(isOverride()).bind("method"), this);
} }
// Re-lex the tokens to get precise locations to insert 'override' and remove // Re-lex the tokens to get precise locations to insert 'override' and remove

View File

@ -127,7 +127,7 @@ void BracesAroundStatementsCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(whileStmt().bind("while"), this); Finder->addMatcher(whileStmt().bind("while"), this);
Finder->addMatcher(doStmt().bind("do"), this); Finder->addMatcher(doStmt().bind("do"), this);
Finder->addMatcher(forStmt().bind("for"), this); Finder->addMatcher(forStmt().bind("for"), this);
Finder->addMatcher(forRangeStmt().bind("for-range"), this); Finder->addMatcher(cxxForRangeStmt().bind("for-range"), this);
} }
void void

View File

@ -75,12 +75,13 @@ void ContainerSizeEmptyCheck::registerMatchers(MatchFinder *Finder) {
hasParent(explicitCastExpr(hasDestinationType(isBoolType())))); hasParent(explicitCastExpr(hasDestinationType(isBoolType()))));
Finder->addMatcher( Finder->addMatcher(
memberCallExpr( cxxMemberCallExpr(
on(expr(anyOf(hasType(namedDecl(stlContainer())), on(expr(anyOf(hasType(namedDecl(stlContainer())),
hasType(pointsTo(namedDecl(stlContainer()))), hasType(pointsTo(namedDecl(stlContainer()))),
hasType(references(namedDecl(stlContainer()))))) hasType(references(namedDecl(stlContainer())))))
.bind("STLObject")), .bind("STLObject")),
callee(methodDecl(hasName("size"))), WrongUse).bind("SizeCallExpr"), callee(cxxMethodDecl(hasName("size"))), WrongUse)
.bind("SizeCallExpr"),
this); this);
} }

View File

@ -36,7 +36,7 @@ void FunctionSizeCheck::registerMatchers(MatchFinder *Finder) {
stmt(unless(compoundStmt()), stmt(unless(compoundStmt()),
hasParent(stmt(anyOf(compoundStmt(), ifStmt(), hasParent(stmt(anyOf(compoundStmt(), ifStmt(),
anyOf(whileStmt(), doStmt(), anyOf(whileStmt(), doStmt(),
forRangeStmt(), forStmt()))))) cxxForRangeStmt(), forStmt())))))
.bind("stmt"))).bind("func"), .bind("stmt"))).bind("func"),
this); this);
} }

View File

@ -19,24 +19,26 @@ namespace readability {
namespace { namespace {
internal::Matcher<Expr> callToGet(internal::Matcher<Decl> OnClass) { internal::Matcher<Expr> callToGet(internal::Matcher<Decl> OnClass) {
return memberCallExpr( return cxxMemberCallExpr(
on(expr(anyOf(hasType(OnClass), on(expr(anyOf(hasType(OnClass),
hasType(qualType(pointsTo(decl(OnClass).bind( hasType(qualType(
"ptr_to_ptr")))))).bind("smart_pointer")), pointsTo(decl(OnClass).bind("ptr_to_ptr"))))))
unless(callee(memberExpr(hasObjectExpression(thisExpr())))), .bind("smart_pointer")),
callee(methodDecl(hasName("get")))).bind("redundant_get"); unless(callee(memberExpr(hasObjectExpression(cxxThisExpr())))),
callee(cxxMethodDecl(hasName("get"))))
.bind("redundant_get");
} }
void registerMatchersForGetArrowStart(MatchFinder *Finder, void registerMatchersForGetArrowStart(MatchFinder *Finder,
MatchFinder::MatchCallback *Callback) { MatchFinder::MatchCallback *Callback) {
const auto QuacksLikeASmartptr = recordDecl( const auto QuacksLikeASmartptr = recordDecl(
recordDecl().bind("duck_typing"), recordDecl().bind("duck_typing"),
has(methodDecl(hasName("operator->"), has(cxxMethodDecl(hasName("operator->"),
returns(qualType(pointsTo(type().bind("op->Type")))))), returns(qualType(pointsTo(type().bind("op->Type")))))),
has(methodDecl(hasName("operator*"), has(cxxMethodDecl(hasName("operator*"),
returns(qualType(references(type().bind("op*Type")))))), returns(qualType(references(type().bind("op*Type")))))),
has(methodDecl(hasName("get"), has(cxxMethodDecl(hasName("get"),
returns(qualType(pointsTo(type().bind("getType"))))))); returns(qualType(pointsTo(type().bind("getType")))))));
// Catch 'ptr.get()->Foo()' // Catch 'ptr.get()->Foo()'
Finder->addMatcher(memberExpr(expr().bind("memberExpr"), isArrow(), Finder->addMatcher(memberExpr(expr().bind("memberExpr"), isArrow(),
@ -63,9 +65,10 @@ void registerMatchersForGetEquals(MatchFinder *Finder,
// Matches against nullptr. // Matches against nullptr.
Finder->addMatcher( Finder->addMatcher(
binaryOperator(anyOf(hasOperatorName("=="), hasOperatorName("!=")), binaryOperator(
hasEitherOperand(ignoringImpCasts(nullPtrLiteralExpr())), anyOf(hasOperatorName("=="), hasOperatorName("!=")),
hasEitherOperand(callToGet(IsAKnownSmartptr))), hasEitherOperand(ignoringImpCasts(cxxNullPtrLiteralExpr())),
hasEitherOperand(callToGet(IsAKnownSmartptr))),
Callback); Callback);
// TODO: Catch ptr.get() == other_ptr.get() // TODO: Catch ptr.get() == other_ptr.get()
} }

View File

@ -86,40 +86,42 @@ void RedundantStringCStrCheck::registerMatchers(
return; return;
Finder->addMatcher( Finder->addMatcher(
constructExpr( cxxConstructExpr(
hasDeclaration(methodDecl(hasName(StringConstructor))), hasDeclaration(cxxMethodDecl(hasName(StringConstructor))),
argumentCountIs(2), argumentCountIs(2),
// The first argument must have the form x.c_str() or p->c_str() // The first argument must have the form x.c_str() or p->c_str()
// where the method is string::c_str(). We can use the copy // where the method is string::c_str(). We can use the copy
// constructor of string instead (or the compiler might share // constructor of string instead (or the compiler might share
// the string object). // the string object).
hasArgument( hasArgument(0, cxxMemberCallExpr(
0, memberCallExpr(callee(memberExpr().bind("member")), callee(memberExpr().bind("member")),
callee(methodDecl(hasName(StringCStrMethod))), callee(cxxMethodDecl(hasName(StringCStrMethod))),
on(expr().bind("arg"))).bind("call")), on(expr().bind("arg")))
.bind("call")),
// The second argument is the alloc object which must not be // The second argument is the alloc object which must not be
// present explicitly. // present explicitly.
hasArgument(1, defaultArgExpr())), hasArgument(1, cxxDefaultArgExpr())),
this); this);
Finder->addMatcher( Finder->addMatcher(
constructExpr( cxxConstructExpr(
// Implicit constructors of these classes are overloaded // Implicit constructors of these classes are overloaded
// wrt. string types and they internally make a StringRef // wrt. string types and they internally make a StringRef
// referring to the argument. Passing a string directly to // referring to the argument. Passing a string directly to
// them is preferred to passing a char pointer. // them is preferred to passing a char pointer.
hasDeclaration( hasDeclaration(
methodDecl(anyOf(hasName("::llvm::StringRef::StringRef"), cxxMethodDecl(anyOf(hasName("::llvm::StringRef::StringRef"),
hasName("::llvm::Twine::Twine")))), hasName("::llvm::Twine::Twine")))),
argumentCountIs(1), argumentCountIs(1),
// The only argument must have the form x.c_str() or p->c_str() // The only argument must have the form x.c_str() or p->c_str()
// where the method is string::c_str(). StringRef also has // where the method is string::c_str(). StringRef also has
// a constructor from string which is more efficient (avoids // a constructor from string which is more efficient (avoids
// strlen), so we can construct StringRef from the string // strlen), so we can construct StringRef from the string
// directly. // directly.
hasArgument( hasArgument(0, cxxMemberCallExpr(
0, memberCallExpr(callee(memberExpr().bind("member")), callee(memberExpr().bind("member")),
callee(methodDecl(hasName(StringCStrMethod))), callee(cxxMethodDecl(hasName(StringCStrMethod))),
on(expr().bind("arg"))).bind("call"))), on(expr().bind("arg")))
.bind("call"))),
this); this);
} }

View File

@ -75,7 +75,8 @@ const CXXBoolLiteralExpr *getBoolLiteral(const MatchFinder::MatchResult &Result,
internal::Matcher<Stmt> returnsBool(bool Value, StringRef Id = "ignored") { internal::Matcher<Stmt> returnsBool(bool Value, StringRef Id = "ignored") {
auto SimpleReturnsBool = auto SimpleReturnsBool =
returnStmt(has(boolLiteral(equals(Value)).bind(Id))).bind("returns-bool"); returnStmt(has(cxxBoolLiteral(equals(Value)).bind(Id)))
.bind("returns-bool");
return anyOf(SimpleReturnsBool, return anyOf(SimpleReturnsBool,
compoundStmt(statementCountIs(1), has(SimpleReturnsBool))); compoundStmt(statementCountIs(1), has(SimpleReturnsBool)));
} }
@ -268,11 +269,12 @@ void SimplifyBooleanExprCheck::matchBoolBinOpExpr(MatchFinder *Finder,
StringRef OperatorName, StringRef OperatorName,
StringRef BooleanId) { StringRef BooleanId) {
Finder->addMatcher( Finder->addMatcher(
binaryOperator(isExpansionInMainFile(), hasOperatorName(OperatorName), binaryOperator(
hasLHS(allOf(expr().bind(LHSId), isExpansionInMainFile(), hasOperatorName(OperatorName),
boolLiteral(equals(Value)).bind(BooleanId))), hasLHS(allOf(expr().bind(LHSId),
hasRHS(expr().bind(RHSId)), cxxBoolLiteral(equals(Value)).bind(BooleanId))),
unless(hasRHS(hasDescendant(boolLiteral())))), hasRHS(expr().bind(RHSId)),
unless(hasRHS(hasDescendant(cxxBoolLiteral())))),
this); this);
} }
@ -284,9 +286,10 @@ void SimplifyBooleanExprCheck::matchExprBinOpBool(MatchFinder *Finder,
binaryOperator( binaryOperator(
isExpansionInMainFile(), hasOperatorName(OperatorName), isExpansionInMainFile(), hasOperatorName(OperatorName),
hasLHS(expr().bind(LHSId)), hasLHS(expr().bind(LHSId)),
unless(hasLHS(anyOf(boolLiteral(), hasDescendant(boolLiteral())))), unless(
hasLHS(anyOf(cxxBoolLiteral(), hasDescendant(cxxBoolLiteral())))),
hasRHS(allOf(expr().bind(RHSId), hasRHS(allOf(expr().bind(RHSId),
boolLiteral(equals(Value)).bind(BooleanId)))), cxxBoolLiteral(equals(Value)).bind(BooleanId)))),
this); this);
} }
@ -297,10 +300,10 @@ void SimplifyBooleanExprCheck::matchBoolCompOpExpr(MatchFinder *Finder,
Finder->addMatcher( Finder->addMatcher(
binaryOperator(isExpansionInMainFile(), hasOperatorName(OperatorName), binaryOperator(isExpansionInMainFile(), hasOperatorName(OperatorName),
hasLHS(allOf(expr().bind(LHSId), hasLHS(allOf(expr().bind(LHSId),
ignoringImpCasts(boolLiteral(equals(Value)) ignoringImpCasts(cxxBoolLiteral(equals(Value))
.bind(BooleanId)))), .bind(BooleanId)))),
hasRHS(expr().bind(RHSId)), hasRHS(expr().bind(RHSId)),
unless(hasRHS(hasDescendant(boolLiteral())))), unless(hasRHS(hasDescendant(cxxBoolLiteral())))),
this); this);
} }
@ -310,10 +313,10 @@ void SimplifyBooleanExprCheck::matchExprCompOpBool(MatchFinder *Finder,
StringRef BooleanId) { StringRef BooleanId) {
Finder->addMatcher( Finder->addMatcher(
binaryOperator(isExpansionInMainFile(), hasOperatorName(OperatorName), binaryOperator(isExpansionInMainFile(), hasOperatorName(OperatorName),
unless(hasLHS(hasDescendant(boolLiteral()))), unless(hasLHS(hasDescendant(cxxBoolLiteral()))),
hasLHS(expr().bind(LHSId)), hasLHS(expr().bind(LHSId)),
hasRHS(allOf(expr().bind(RHSId), hasRHS(allOf(expr().bind(RHSId),
ignoringImpCasts(boolLiteral(equals(Value)) ignoringImpCasts(cxxBoolLiteral(equals(Value))
.bind(BooleanId))))), .bind(BooleanId))))),
this); this);
} }
@ -323,7 +326,7 @@ void SimplifyBooleanExprCheck::matchBoolCondition(MatchFinder *Finder,
StringRef BooleanId) { StringRef BooleanId) {
Finder->addMatcher( Finder->addMatcher(
ifStmt(isExpansionInMainFile(), ifStmt(isExpansionInMainFile(),
hasCondition(boolLiteral(equals(Value)).bind(BooleanId))) hasCondition(cxxBoolLiteral(equals(Value)).bind(BooleanId)))
.bind(IfStmtId), .bind(IfStmtId),
this); this);
} }
@ -333,8 +336,8 @@ void SimplifyBooleanExprCheck::matchTernaryResult(MatchFinder *Finder,
StringRef TernaryId) { StringRef TernaryId) {
Finder->addMatcher( Finder->addMatcher(
conditionalOperator(isExpansionInMainFile(), conditionalOperator(isExpansionInMainFile(),
hasTrueExpression(boolLiteral(equals(Value))), hasTrueExpression(cxxBoolLiteral(equals(Value))),
hasFalseExpression(boolLiteral(equals(!Value)))) hasFalseExpression(cxxBoolLiteral(equals(!Value))))
.bind(TernaryId), .bind(TernaryId),
this); this);
} }
@ -363,13 +366,13 @@ void SimplifyBooleanExprCheck::matchIfAssignsBool(MatchFinder *Finder,
hasOperatorName("="), hasOperatorName("="),
hasLHS(declRefExpr(hasDeclaration(decl().bind(IfAssignObjId)))), hasLHS(declRefExpr(hasDeclaration(decl().bind(IfAssignObjId)))),
hasLHS(expr().bind(IfAssignVariableId)), hasLHS(expr().bind(IfAssignVariableId)),
hasRHS(boolLiteral(equals(Value)).bind(IfAssignLocId))); hasRHS(cxxBoolLiteral(equals(Value)).bind(IfAssignLocId)));
auto Then = anyOf(SimpleThen, compoundStmt(statementCountIs(1), auto Then = anyOf(SimpleThen, compoundStmt(statementCountIs(1),
hasAnySubstatement(SimpleThen))); hasAnySubstatement(SimpleThen)));
auto SimpleElse = binaryOperator( auto SimpleElse = binaryOperator(
hasOperatorName("="), hasOperatorName("="),
hasLHS(declRefExpr(hasDeclaration(equalsBoundNode(IfAssignObjId)))), hasLHS(declRefExpr(hasDeclaration(equalsBoundNode(IfAssignObjId)))),
hasRHS(boolLiteral(equals(!Value)))); hasRHS(cxxBoolLiteral(equals(!Value))));
auto Else = anyOf(SimpleElse, compoundStmt(statementCountIs(1), auto Else = anyOf(SimpleElse, compoundStmt(statementCountIs(1),
hasAnySubstatement(SimpleElse))); hasAnySubstatement(SimpleElse)));
if (ChainedConditionalAssignment) { if (ChainedConditionalAssignment) {
@ -389,11 +392,11 @@ void SimplifyBooleanExprCheck::matchCompoundIfReturnsBool(MatchFinder *Finder,
bool Value, bool Value,
StringRef Id) { StringRef Id) {
Finder->addMatcher( Finder->addMatcher(
compoundStmt( compoundStmt(allOf(hasAnySubstatement(ifStmt(hasThen(returnsBool(Value)),
allOf(hasAnySubstatement(ifStmt(hasThen(returnsBool(Value)), unless(hasElse(stmt())))),
unless(hasElse(stmt())))), hasAnySubstatement(
hasAnySubstatement(returnStmt(has(boolLiteral(equals(!Value)))) returnStmt(has(cxxBoolLiteral(equals(!Value))))
.bind(CompoundReturnId)))) .bind(CompoundReturnId))))
.bind(Id), .bind(Id),
this); this);
} }