bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const { unsigned MatchCount = 0; for (llvm::ArrayRef<ASTUnit *>::iterator I = QS.ASTs.begin(), E = QS.ASTs.end(); I != E; ++I) { ASTUnit *AST = *I; MatchFinder Finder; std::vector<BoundNodes> Matches; DynTypedMatcher MaybeBoundMatcher = Matcher; if (QS.BindRoot) { llvm::Optional<DynTypedMatcher> M = Matcher.tryBind("root"); if (M) MaybeBoundMatcher = *M; } CollectBoundNodes Collect(Matches); if (!Finder.addDynamicMatcher(MaybeBoundMatcher, &Collect)) { OS << "Not a valid top-level matcher.\n"; return false; } Finder.matchAST(AST->getASTContext()); for (std::vector<BoundNodes>::iterator MI = Matches.begin(), ME = Matches.end(); MI != ME; ++MI) { OS << "\nMatch #" << ++MatchCount << ":\n\n"; for (BoundNodes::IDToNodeMap::const_iterator BI = MI->getMap().begin(), BE = MI->getMap().end(); BI != BE; ++BI) { switch (QS.OutKind) { case OK_Diag: { clang::SourceRange R = BI->second.getSourceRange(); if (R.isValid()) { TextDiagnostic TD(OS, AST->getASTContext().getLangOpts(), &AST->getDiagnostics().getDiagnosticOptions()); TD.emitDiagnostic( R.getBegin(), DiagnosticsEngine::Note, "\"" + BI->first + "\" binds here", ArrayRef<CharSourceRange>(CharSourceRange::getTokenRange(R)), ArrayRef<FixItHint>(), &AST->getSourceManager()); } break; } case OK_Print: { OS << "Binding for \"" << BI->first << "\":\n"; BI->second.print(OS, AST->getASTContext().getPrintingPolicy()); OS << "\n"; break; } case OK_Dump: { OS << "Binding for \"" << BI->first << "\":\n"; BI->second.dump(OS, AST->getSourceManager()); OS << "\n"; break; } } } if (MI->getMap().empty()) OS << "No bindings.\n"; } } OS << MatchCount << (MatchCount == 1 ? " match.\n" : " matches.\n"); return true; }
bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const { unsigned MatchCount = 0; for (auto &AST : QS.ASTs) { MatchFinder Finder; std::vector<BoundNodes> Matches; DynTypedMatcher MaybeBoundMatcher = Matcher; if (QS.BindRoot) { llvm::Optional<DynTypedMatcher> M = Matcher.tryBind("root"); if (M) MaybeBoundMatcher = *M; } CollectBoundNodes Collect(Matches); if (!Finder.addDynamicMatcher(MaybeBoundMatcher, &Collect)) { OS << "Not a valid top-level matcher.\n"; return false; } Finder.matchAST(AST->getASTContext()); if (QS.PrintMatcher) { std::string prefixText = "Matcher: "; OS << "\n " << prefixText << Source << "\n"; OS << " " << std::string(prefixText.size() + Source.size(), '=') << '\n'; } for (auto MI = Matches.begin(), ME = Matches.end(); MI != ME; ++MI) { OS << "\nMatch #" << ++MatchCount << ":\n\n"; for (auto BI = MI->getMap().begin(), BE = MI->getMap().end(); BI != BE; ++BI) { if (QS.DiagOutput) { clang::SourceRange R = BI->second.getSourceRange(); if (R.isValid()) { TextDiagnostic TD(OS, AST->getASTContext().getLangOpts(), &AST->getDiagnostics().getDiagnosticOptions()); TD.emitDiagnostic( FullSourceLoc(R.getBegin(), AST->getSourceManager()), DiagnosticsEngine::Note, "\"" + BI->first + "\" binds here", CharSourceRange::getTokenRange(R), None); } } if (QS.PrintOutput) { OS << "Binding for \"" << BI->first << "\":\n"; BI->second.print(OS, AST->getASTContext().getPrintingPolicy()); OS << "\n"; } if (QS.DetailedASTOutput) { OS << "Binding for \"" << BI->first << "\":\n"; BI->second.dump(OS, AST->getSourceManager()); OS << "\n"; } } if (MI->getMap().empty()) OS << "No bindings.\n"; } } OS << MatchCount << (MatchCount == 1 ? " match.\n" : " matches.\n"); return true; }