class UnusedParametersCheck::IndexerVisitor
: public RecursiveASTVisitor<IndexerVisitor> {
public:
- IndexerVisitor(TranslationUnitDecl *Top) { TraverseDecl(Top); }
+ IndexerVisitor(ASTContext &Ctx) { TraverseAST(Ctx); }
const std::unordered_set<const CallExpr *> &
getFnCalls(const FunctionDecl *Fn) {
auto MyDiag = diag(Param->getLocation(), "parameter %0 is unused") << Param;
if (!Indexer) {
- Indexer = llvm::make_unique<IndexerVisitor>(
- Result.Context->getTranslationUnitDecl());
+ Indexer = llvm::make_unique<IndexerVisitor>(*Result.Context);
}
// Comment out parameter name for non-local functions.
// variable declared inside the loop outside of it.
// FIXME: Determine when the external dependency isn't an expression converted
// by another loop.
- TUInfo->getParentFinder().gatherAncestors(Context->getTranslationUnitDecl());
+ TUInfo->getParentFinder().gatherAncestors(*Context);
DependencyFinderASTVisitor DependencyFinder(
&TUInfo->getParentFinder().getStmtToParentStmtMap(),
&TUInfo->getParentFinder().getDeclToParentStmtMap(),
public:
StmtAncestorASTVisitor() { StmtStack.push_back(nullptr); }
- /// \brief Run the analysis on the TranslationUnitDecl.
+ /// \brief Run the analysis on the AST.
///
/// In case we're running this analysis multiple times, don't repeat the work.
- void gatherAncestors(const clang::TranslationUnitDecl *T) {
+ void gatherAncestors(ASTContext &Ctx) {
if (StmtAncestors.empty())
- TraverseDecl(const_cast<clang::TranslationUnitDecl *>(T));
+ TraverseAST(Ctx);
}
/// Accessor for StmtAncestors.
ChainedConditionalAssignment);
}
+// This is a silly hack to let us run a RecursiveASTVisitor on the Context.
+// We want to match exactly one node in the AST, doesn't matter which.
+AST_MATCHER_P(Decl, matchOnce, bool *, Matched) {
+ if (*Matched)
+ return false;
+ return *Matched = true;
+}
+
void SimplifyBooleanExprCheck::registerMatchers(MatchFinder *Finder) {
- Finder->addMatcher(translationUnitDecl().bind("top"), this);
+ Finder->addMatcher(matchOnce(&MatchedOnce), this);
matchBoolCondition(Finder, true, ConditionThenStmtId);
matchBoolCondition(Finder, false, ConditionElseStmtId);
else if (const auto *Compound =
Result.Nodes.getNodeAs<CompoundStmt>(CompoundNotBoolId))
replaceCompoundReturnWithCondition(Result, Compound, true);
- else if (const auto TU = Result.Nodes.getNodeAs<Decl>("top"))
- Visitor(this, Result).TraverseDecl(const_cast<Decl*>(TU));
+ else { // MatchOnce matcher
+ assert(MatchedOnce);
+ Visitor(this, Result).TraverseAST(*Result.Context);
+ }
}
void SimplifyBooleanExprCheck::issueDiag(
SourceLocation Loc, StringRef Description,
SourceRange ReplacementRange, StringRef Replacement);
+ bool MatchedOnce = false;
const bool ChainedConditionalReturn;
const bool ChainedConditionalAssignment;
};