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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits