From 39fff696974a26b44f562761367074cfcdca3236 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Wed, 1 Aug 2018 18:33:04 +0000 Subject: [PATCH] [llvm-undname Add an option to dump back references. This is useful for understanding how our demangler processes back references and for investigating issues related to back references. But it's a feature only useful for debugging the demangling process itself, so I'm marking it hidden. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338609 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Demangle/Demangle.h | 4 +++- lib/Demangle/MicrosoftDemangle.cpp | 35 ++++++++++++++++++++++++++++- tools/llvm-undname/llvm-undname.cpp | 10 ++++++++- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/include/llvm/Demangle/Demangle.h b/include/llvm/Demangle/Demangle.h index df7753f23b8..27340b77aa2 100644 --- a/include/llvm/Demangle/Demangle.h +++ b/include/llvm/Demangle/Demangle.h @@ -27,8 +27,10 @@ enum : int { char *itaniumDemangle(const char *mangled_name, char *buf, size_t *n, int *status); + +enum MSDemangleFlags { MSDF_None = 0, MSDF_DumpBackrefs = 1 << 0 }; char *microsoftDemangle(const char *mangled_name, char *buf, size_t *n, - int *status); + int *status, MSDemangleFlags Flags = MSDF_None); /// "Partial" demangler. This supports demangling a string into an AST /// (typically an intermediate stage in itaniumDemangle) and querying certain diff --git a/lib/Demangle/MicrosoftDemangle.cpp b/lib/Demangle/MicrosoftDemangle.cpp index 04575818422..9cf7c4bb127 100644 --- a/lib/Demangle/MicrosoftDemangle.cpp +++ b/lib/Demangle/MicrosoftDemangle.cpp @@ -878,6 +878,8 @@ public: // True if an error occurred. bool Error = false; + void dumpBackReferences(); + private: Type *demangleVariableEncoding(StringView &MangledName); Type *demangleFunctionEncoding(StringView &MangledName); @@ -2046,12 +2048,43 @@ void Demangler::output(const Symbol *S, OutputStream &OS) { Type::outputPost(OS, *S->SymbolType); } +void Demangler::dumpBackReferences() { + printf("%d function parameter backreferences\n", + (int)FunctionParamBackRefCount); + + // Create an output stream so we can render each type. + OutputStream OS = OutputStream::create(nullptr, 0, 1024); + for (size_t I = 0; I < FunctionParamBackRefCount; ++I) { + OS.setCurrentPosition(0); + + Type *T = FunctionParamBackRefs[I]; + Type::outputPre(OS, *T); + Type::outputPost(OS, *T); + + printf(" [%d] - %*s\n", (int)I, (int)OS.getCurrentPosition(), + OS.getBuffer()); + } + std::free(OS.getBuffer()); + + if (FunctionParamBackRefCount > 0) + printf("\n"); + printf("%d name backreferences\n", (int)BackRefCount); + for (size_t I = 0; I < BackRefCount; ++I) { + printf(" [%d] - %*s\n", (int)I, (int)BackReferences[I].size(), + BackReferences[I].begin()); + } + if (BackRefCount > 0) + printf("\n"); +} + char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N, - int *Status) { + int *Status, MSDemangleFlags Flags) { Demangler D; StringView Name{MangledName}; Symbol *S = D.parse(Name); + if (Flags & MSDF_DumpBackrefs) + D.dumpBackReferences(); OutputStream OS = OutputStream::create(Buf, N, 1024); if (D.Error) { OS << MangledName; diff --git a/tools/llvm-undname/llvm-undname.cpp b/tools/llvm-undname/llvm-undname.cpp index 2124ec16945..31d0590af2d 100644 --- a/tools/llvm-undname/llvm-undname.cpp +++ b/tools/llvm-undname/llvm-undname.cpp @@ -26,12 +26,20 @@ using namespace llvm; +cl::opt DumpBackReferences("backrefs", cl::Optional, + cl::desc("dump backreferences"), cl::Hidden, + cl::init(false)); cl::list Symbols(cl::Positional, cl::desc(""), cl::ZeroOrMore); static void demangle(const std::string &S) { int Status; - char *ResultBuf = microsoftDemangle(S.c_str(), nullptr, nullptr, &Status); + MSDemangleFlags Flags = MSDF_None; + if (DumpBackReferences) + Flags = MSDemangleFlags(Flags | MSDF_DumpBackrefs); + + char *ResultBuf = + microsoftDemangle(S.c_str(), nullptr, nullptr, &Status, Flags); if (Status == llvm::demangle_success) { outs() << ResultBuf << "\n"; outs().flush();