|
19 | 19 | #include "clang/Basic/Module.h"
|
20 | 20 | #include "clang/Basic/SourceManager.h"
|
21 | 21 | #include "llvm/Support/raw_ostream.h"
|
| 22 | + |
22 | 23 | using namespace clang;
|
23 | 24 | using namespace clang::comments;
|
24 | 25 |
|
| 26 | +void ASTDumper::dumpInvalidDeclContext(const DeclContext *DC) { |
| 27 | + NodeDumper.AddChild([=] { |
| 28 | + if (!DC) { |
| 29 | + ColorScope Color(OS, ShowColors, NullColor); |
| 30 | + OS << "<<<NULL>>>"; |
| 31 | + return; |
| 32 | + } |
| 33 | + // An invalid DeclContext is one for which a dyn_cast() from a DeclContext |
| 34 | + // pointer to a Decl pointer would fail an assertion or otherwise fall prey |
| 35 | + // to undefined behavior as a result of an invalid associated DeclKind. |
| 36 | + // Such invalidity is not supposed to happen of course, but, when it does, |
| 37 | + // the information provided below is intended to provide some hints about |
| 38 | + // what might have gone awry. |
| 39 | + { |
| 40 | + ColorScope Color(OS, ShowColors, DeclKindNameColor); |
| 41 | + OS << "DeclContext"; |
| 42 | + } |
| 43 | + NodeDumper.dumpPointer(DC); |
| 44 | + OS << " <"; |
| 45 | + { |
| 46 | + ColorScope Color(OS, ShowColors, DeclNameColor); |
| 47 | + OS << "unrecognized Decl kind " << (unsigned)DC->getDeclKind(); |
| 48 | + } |
| 49 | + OS << ">"; |
| 50 | + }); |
| 51 | +} |
| 52 | + |
25 | 53 | void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
|
26 | 54 | NodeDumper.AddChild([=] {
|
27 | 55 | OS << "StoredDeclsMap ";
|
@@ -200,6 +228,31 @@ LLVM_DUMP_METHOD void Decl::dumpColor() const {
|
200 | 228 | P.Visit(this);
|
201 | 229 | }
|
202 | 230 |
|
| 231 | +LLVM_DUMP_METHOD void DeclContext::dumpAsDecl() const { |
| 232 | + dumpAsDecl(nullptr); |
| 233 | +} |
| 234 | + |
| 235 | +LLVM_DUMP_METHOD void DeclContext::dumpAsDecl(const ASTContext *Ctx) const { |
| 236 | + // By design, DeclContext is required to be a base class of some class that |
| 237 | + // derives from Decl. Thus, it should always be possible to dyn_cast() from |
| 238 | + // a DeclContext pointer to a Decl pointer and Decl::castFromDeclContext() |
| 239 | + // asserts that to be the case. Since this function is intended for use in a |
| 240 | + // debugger, it performs an additional check in order to prevent a failed |
| 241 | + // cast and assertion. If that check fails, then the (invalid) DeclContext |
| 242 | + // is dumped with an indication of its invalidity. |
| 243 | + if (hasValidDeclKind()) { |
| 244 | + const auto *D = cast<Decl>(this); |
| 245 | + D->dump(); |
| 246 | + } else { |
| 247 | + // If an ASTContext is not available, a less capable ASTDumper is |
| 248 | + // constructed for which color diagnostics are, regrettably, disabled. |
| 249 | + ASTDumper P = Ctx ? ASTDumper(llvm::errs(), *Ctx, |
| 250 | + Ctx->getDiagnostics().getShowColors()) |
| 251 | + : ASTDumper(llvm::errs(), /*ShowColors*/ false); |
| 252 | + P.dumpInvalidDeclContext(this); |
| 253 | + } |
| 254 | +} |
| 255 | + |
203 | 256 | LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
|
204 | 257 | dumpLookups(llvm::errs());
|
205 | 258 | }
|
|
0 commit comments