njames93 updated this revision to Diff 404350. njames93 marked 5 inline comments as done. njames93 added a comment.
Refactored implementation to not store state in ClangTidyContext. This will let external consumers of clang-tidy opt into the behaviour. As well as integrate the reporting to any signal handlers they may be using. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D118520/new/ https://reviews.llvm.org/D118520 Files: clang-tools-extra/clang-tidy/ClangTidyCheck.cpp clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
Index: clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp =================================================================== --- clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp +++ clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp @@ -20,6 +20,7 @@ #include "../GlobList.h" #include "clang/Tooling/CommonOptionsParser.h" #include "llvm/Support/InitLLVM.h" +#include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Process.h" #include "llvm/Support/Signals.h" #include "llvm/Support/TargetSelect.h" @@ -384,6 +385,12 @@ return FS; } +class ClangTidyCrashTraceReporter : public llvm::PrettyStackTraceEntry, + public CurProcessingCheckState { +public: + void print(raw_ostream &OS) const override { return dump(OS); } +}; + int clangTidyMain(int argc, const char **argv) { llvm::InitLLVM X(argc, argv); llvm::Expected<CommonOptionsParser> OptionsParser = @@ -488,8 +495,11 @@ llvm::InitializeAllTargetMCs(); llvm::InitializeAllAsmParsers(); + ClangTidyCrashTraceReporter Trace; + ClangTidyContext Context(std::move(OwningOptionsProvider), AllowEnablingAnalyzerAlphaCheckers); + Context.setCrashTraceEngine(&Trace); std::vector<ClangTidyError> Errors = runClangTidy(Context, OptionsParser->getCompilations(), PathList, BaseFS, FixNotes, EnableCheckProfile, ProfilePrefix); Index: clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h =================================================================== --- clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h +++ clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h @@ -23,6 +23,7 @@ class CompilerInstance; class SourceManager; namespace ast_matchers { +class BoundNodes; class MatchFinder; } // namespace ast_matchers namespace tooling { @@ -61,6 +62,31 @@ } }; +class CurProcessingCheckState { +public: + void dump(raw_ostream &OS) const; + void onProcessingCheckStart(StringRef CheckName, + const ast_matchers::BoundNodes &BoundNodes) { + assert(CurContext && "ASTContext not set"); + CurrentCheckName = CheckName; + CurNodes = &BoundNodes; + } + + void onProcessingCheckEnd() { + CurrentCheckName = ""; + CurNodes = nullptr; + } + + void setContext(const ASTContext &Ctx) { CurContext = &Ctx; } + + void clearContext() { CurContext = nullptr; } + +private: + mutable StringRef CurrentCheckName; + const ast_matchers::BoundNodes *CurNodes; + const ASTContext *CurContext; +}; + /// Every \c ClangTidyCheck reports errors through a \c DiagnosticsEngine /// provided by this context. /// @@ -82,6 +108,10 @@ this->DiagEngine = DiagEngine; } + void setCrashTraceEngine(CurProcessingCheckState *State) { + this->CurrentlyProcessing = State; + } + ~ClangTidyContext(); /// Report any errors detected using this method. @@ -204,12 +234,24 @@ DiagEngine->getDiagnosticIDs()->getDescription(DiagnosticID))); } + void onProcessingCheckStart(StringRef CheckName, + const ast_matchers::BoundNodes &Result) const { + if (CurrentlyProcessing) + CurrentlyProcessing->onProcessingCheckStart(CheckName, Result); + } + + void onProcessingCheckEnd() const { + if (CurrentlyProcessing) + CurrentlyProcessing->onProcessingCheckEnd(); + } + private: // Writes to Stats. friend class ClangTidyDiagnosticConsumer; DiagnosticsEngine *DiagEngine; std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider; + CurProcessingCheckState *CurrentlyProcessing; std::string CurrentFile; ClangTidyOptions CurrentOptions; Index: clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp =================================================================== --- clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -22,6 +22,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/ASTDiagnostic.h" #include "clang/AST/Attr.h" +#include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileManager.h" @@ -161,7 +162,7 @@ std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider, bool AllowEnablingAnalyzerAlphaCheckers) : DiagEngine(nullptr), OptionsProvider(std::move(OptionsProvider)), - Profile(false), + CurrentlyProcessing(nullptr), Profile(false), AllowEnablingAnalyzerAlphaCheckers(AllowEnablingAnalyzerAlphaCheckers) { // Before the first translation unit we can get errors related to command-line // parsing, use empty string for the file name in this case. @@ -231,6 +232,8 @@ void ClangTidyContext::setASTContext(ASTContext *Context) { DiagEngine->SetArgToStringFn(&FormatASTNodeDiagnosticArgument, Context); LangOpts = Context->getLangOpts(); + if (CurrentlyProcessing) + CurrentlyProcessing->setContext(*Context); } const ClangTidyGlobalOptions &ClangTidyContext::getGlobalOptions() const { @@ -337,10 +340,30 @@ } return Result; } - } // namespace tidy } // namespace clang +void CurProcessingCheckState::dump(raw_ostream &OS) const { + if (CurrentCheckName.empty()) + return; + // This should be an assert, but asserts shouldn't be used in signal + // handlers + if (!CurContext) + return; + OS << "Processing check " << CurrentCheckName << '\n'; + CurrentCheckName = ""; + const clang::ast_matchers::BoundNodes::IDToNodeMap &Map = CurNodes->getMap(); + if (Map.empty()) { + OS << "No bound nodes\n"; + return; + } + for (const auto &Item : Map) { + OS << "Node '" << Item.first << "' - "; + Item.second.dump(OS, *CurContext); + OS << "\n"; + } +} + void ClangTidyDiagnosticConsumer::HandleDiagnostic( DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) { if (LastErrorWasIgnored && DiagLevel == DiagnosticsEngine::Note) Index: clang-tools-extra/clang-tidy/ClangTidyCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/ClangTidyCheck.cpp +++ clang-tools-extra/clang-tidy/ClangTidyCheck.cpp @@ -39,10 +39,12 @@ } void ClangTidyCheck::run(const ast_matchers::MatchFinder::MatchResult &Result) { + Context->onProcessingCheckStart(CheckName, Result.Nodes); // For historical reasons, checks don't implement the MatchFinder run() // callback directly. We keep the run()/check() distinction to avoid interface // churn, and to allow us to add cross-cutting logic in the future. check(Result); + Context->onProcessingCheckEnd(); } ClangTidyCheck::OptionsView::OptionsView(
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits