forked from OSchip/llvm-project
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:
parent
512fb64765
commit
b9ea09c445
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)));
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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>>
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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")),
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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")));
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))));
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue