tahonermann updated this revision to Diff 464488.
tahonermann marked 9 inline comments as done.
tahonermann added a comment.
Addressed a suggested edit I originally failed to notice.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D133499/new/
https://reviews.llvm.org/D133499
Files:
clang/include/clang/AST/ASTDumper.h
clang/include/clang/AST/DeclBase.h
clang/lib/AST/ASTDumper.cpp
clang/lib/AST/DeclBase.cpp
Index: clang/lib/AST/DeclBase.cpp
===================================================================
--- clang/lib/AST/DeclBase.cpp
+++ clang/lib/AST/DeclBase.cpp
@@ -152,6 +152,15 @@
}
}
+bool DeclContext::hasValidDeclKind() const {
+ switch (getDeclKind()) {
+#define DECL(DERIVED, BASE) case Decl::DERIVED: return true;
+#define ABSTRACT_DECL(DECL)
+#include "clang/AST/DeclNodes.inc"
+ }
+ return false;
+}
+
const char *DeclContext::getDeclKindName() const {
switch (getDeclKind()) {
#define DECL(DERIVED, BASE) case Decl::DERIVED: return #DERIVED;
Index: clang/lib/AST/ASTDumper.cpp
===================================================================
--- clang/lib/AST/ASTDumper.cpp
+++ clang/lib/AST/ASTDumper.cpp
@@ -19,9 +19,37 @@
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/Support/raw_ostream.h"
+
using namespace clang;
using namespace clang::comments;
+void ASTDumper::dumpInvalidDeclContext(const DeclContext *DC) {
+ NodeDumper.AddChild([=] {
+ if (!DC) {
+ ColorScope Color(OS, ShowColors, NullColor);
+ OS << "<<<NULL>>>";
+ return;
+ }
+ // An invalid DeclContext is one for which a dyn_cast() from a DeclContext
+ // pointer to a Decl pointer would fail an assertion or otherwise fall prey
+ // to undefined behavior as a result of an invalid associated DeclKind.
+ // Such invalidity is not supposed to happen of course, but, when it does,
+ // the information provided below is intended to provide some hints about
+ // what might have gone awry.
+ {
+ ColorScope Color(OS, ShowColors, DeclKindNameColor);
+ OS << "DeclContext";
+ }
+ NodeDumper.dumpPointer(DC);
+ OS << " <";
+ {
+ ColorScope Color(OS, ShowColors, DeclNameColor);
+ OS << "unrecognized Decl kind " << (unsigned)DC->getDeclKind();
+ }
+ OS << ">";
+ });
+}
+
void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
NodeDumper.AddChild([=] {
OS << "StoredDeclsMap ";
@@ -200,6 +228,37 @@
P.Visit(this);
}
+LLVM_DUMP_METHOD void DeclContext::dumpAsDecl() const {
+ dumpAsDecl(nullptr);
+}
+
+LLVM_DUMP_METHOD void DeclContext::dumpAsDecl(const ASTContext *Ctx) const {
+ // By design, every DeclContext instance is required to be a base class of
+ // some class that derives from Decl. Thus, it should always be possible to
+ // dyn_cast() from a DeclContext pointer to a Decl pointer and, indeed,
+ // the innerworkings of dyn_cast() do assert that to be the case! Alas,
+ // strange and unfortunate things do occasionally occur that lead to folk
+ // like yourself, dear reader, running a debugger and feeling extraordinarily
+ // curious about the origin of a DeclContext instance for which you have
+ // little knowledge. This function has been carefully designed to provide you,
+ // yes you, the answers you desperately seek and deserve with minimal risk
+ // that simply asking the question will upend your debugging experience. The
+ // call to dyn_cast() below is guarded by a validity check that ensures its
+ // success, thus preventing an otherwise potentially volatile (no, not that
+ // kind of volatile) situation.
+ if (hasValidDeclKind()) {
+ const auto *D = dyn_cast<Decl>(this);
+ D->dump();
+ } else {
+ // If an ASTContext is not available, a less capable ASTDumper is
+ // constructed for which color diagnostics are, regrettably, disabled.
+ ASTDumper P = Ctx ? ASTDumper(llvm::errs(), *Ctx,
+ Ctx->getDiagnostics().getShowColors())
+ : ASTDumper(llvm::errs(), /*ShowColors*/ false);
+ P.dumpInvalidDeclContext(this);
+ }
+}
+
LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
dumpLookups(llvm::errs());
}
Index: clang/include/clang/AST/DeclBase.h
===================================================================
--- clang/include/clang/AST/DeclBase.h
+++ clang/include/clang/AST/DeclBase.h
@@ -1906,6 +1906,10 @@
public:
~DeclContext();
+ // For use when debugging; hasValidDeclKind() will always return true for
+ // a correctly constructed object within its lifetime.
+ bool hasValidDeclKind() const;
+
Decl::Kind getDeclKind() const {
return static_cast<Decl::Kind>(DeclContextBits.DeclKind);
}
@@ -2527,6 +2531,8 @@
static bool classof(const Decl *D);
static bool classof(const DeclContext *D) { return true; }
+ void dumpAsDecl() const;
+ void dumpAsDecl(const ASTContext *Ctx) const;
void dumpDeclContext() const;
void dumpLookups() const;
void dumpLookups(llvm::raw_ostream &OS, bool DumpDecls = false,
Index: clang/include/clang/AST/ASTDumper.h
===================================================================
--- clang/include/clang/AST/ASTDumper.h
+++ clang/include/clang/AST/ASTDumper.h
@@ -32,6 +32,7 @@
TextNodeDumper &doGetNodeDelegate() { return NodeDumper; }
+ void dumpInvalidDeclContext(const DeclContext *DC);
void dumpLookups(const DeclContext *DC, bool DumpDecls);
template <typename SpecializationDecl>
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits