njames93 updated this revision to Diff 405111.
njames93 added a comment.

Added release notes.
Remove AST dump of bound nodes, typically isn't very helpful


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
  clang-tools-extra/docs/ReleaseNotes.rst

Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -76,6 +76,9 @@
 - Added support for `NOLINTBEGIN` ... `NOLINTEND` comments to suppress
   Clang-Tidy warnings over multiple lines.
 
+- Added trace code to help narrow down any checks and the relevant source code
+  that result in crashes.
+
 New checks
 ^^^^^^^^^^
 
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
@@ -22,6 +22,10 @@
 class ASTContext;
 class SourceManager;
 
+namespace ast_matchers {
+class BoundNodes;
+} // namespace ast_matchers
+
 namespace tidy {
 class CachedGlobList;
 
@@ -54,6 +58,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.
 ///
@@ -75,6 +104,10 @@
     this->DiagEngine = DiagEngine;
   }
 
+  void setCrashTraceEngine(CurProcessingCheckState *State) {
+    this->CurrentlyProcessing = State;
+  }
+
   ~ClangTidyContext();
 
   /// Report any errors detected using this method.
@@ -197,12 +230,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,51 @@
   }
   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;
+  }
+  OS << "--- Bound Nodes Begin ---\n";
+  for (const auto &Item : Map) {
+    OS << "    " << Item.first << " - { ";
+    if (const auto *D = Item.second.get<Decl>()) {
+      OS << D->getDeclKindName() << "Decl : ";
+      if (const auto *ND = dyn_cast<NamedDecl>(D))
+        OS << ND->getDeclName() << " ";
+      else
+        OS << "<anonymous> ";
+      D->getSourceRange().print(OS, CurContext->getSourceManager());
+    } else if (const auto *S = Item.second.get<Stmt>()) {
+      OS << S->getStmtClassName() << " : ";
+      S->getSourceRange().print(OS, CurContext->getSourceManager());
+    } else if (const auto *T = Item.second.get<Type>()) {
+      OS << T->getTypeClassName() << "Type : ";
+      T->dump(OS, *CurContext);
+    } else if (const auto *QT = Item.second.get<QualType>()) {
+      OS << "QualType : ";
+      QT->print(OS, CurContext->getPrintingPolicy());
+    } else {
+      OS << Item.second.getNodeKind().asStringRef() << " : ";
+      Item.second.getSourceRange().print(OS, CurContext->getSourceManager());
+    }
+    OS << "}\n";
+  }
+  OS << "--- Bound Nodes End ---\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

Reply via email to