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