[llvm] 5f57793 - * NFC. Refactored DIPrinter for better support of new print styles.

Alex Orlov via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 5 04:40:55 PDT 2021


Author: Alex Orlov
Date: 2021-04-05T15:40:41+04:00
New Revision: 5f57793c4fe47aa3486a755768b43189351cbd15

URL: https://github.com/llvm/llvm-project/commit/5f57793c4fe47aa3486a755768b43189351cbd15
DIFF: https://github.com/llvm/llvm-project/commit/5f57793c4fe47aa3486a755768b43189351cbd15.diff

LOG: * NFC. Refactored DIPrinter for better support of new print styles.

This patch introduces a DIPrinter interface to implement by different output style printer implementations. DIPrinterGNU and DIPrinterLLVM implement the GNU and LLVM output style printing respectively. No functional changes.

This refactoring clarifies and simplifies the code, and makes a new output style addition easier.

Reviewed By: jhenderson, dblaikie

Differential Revision: https://reviews.llvm.org/D98994

Added: 
    

Modified: 
    llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h
    llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
    llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h b/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h
index 3d7e06992182d..66409d86c6da8 100644
--- a/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h
+++ b/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h
@@ -14,46 +14,105 @@
 #ifndef LLVM_DEBUGINFO_SYMBOLIZE_DIPRINTER_H
 #define LLVM_DEBUGINFO_SYMBOLIZE_DIPRINTER_H
 
+#include "llvm/ADT/StringRef.h"
 #include <string>
+#include <vector>
 
 namespace llvm {
 struct DILineInfo;
 class DIInliningInfo;
 struct DIGlobal;
 struct DILocal;
+class ErrorInfoBase;
 class raw_ostream;
 
 namespace symbolize {
 
+struct Request {
+  StringRef ModuleName;
+  uint64_t Address = 0;
+};
+
 class DIPrinter {
 public:
-  enum class OutputStyle { LLVM, GNU };
+  DIPrinter(){};
+  virtual ~DIPrinter(){};
 
-private:
-  raw_ostream &OS;
-  bool PrintFunctionNames;
-  bool PrintPretty;
-  int PrintSourceContext;
+  virtual void print(const Request &Request, const DILineInfo &Info) = 0;
+  virtual void print(const Request &Request, const DIInliningInfo &Info) = 0;
+  virtual void print(const Request &Request, const DIGlobal &Global) = 0;
+  virtual void print(const Request &Request,
+                     const std::vector<DILocal> &Locals) = 0;
+
+  virtual void printInvalidCommand(const Request &Request,
+                                   const ErrorInfoBase &ErrorInfo) = 0;
+
+  virtual bool printError(const Request &Request,
+                          const ErrorInfoBase &ErrorInfo,
+                          StringRef ErrorBanner) = 0;
+};
+
+struct PrinterConfig {
+  bool PrintAddress;
+  bool PrintFunctions;
+  bool Pretty;
   bool Verbose;
-  OutputStyle Style;
+  int SourceContextLines;
+};
+
+class PlainPrinterBase : public DIPrinter {
+protected:
+  raw_ostream &OS;
+  raw_ostream &ES;
+  PrinterConfig Config;
 
   void print(const DILineInfo &Info, bool Inlined);
-  void printContext(const std::string &FileName, int64_t Line);
+  void printFunctionName(StringRef FunctionName, bool Inlined);
+  virtual void printSimpleLocation(StringRef Filename,
+                                   const DILineInfo &Info) = 0;
+  void printContext(StringRef FileName, int64_t Line);
+  void printVerbose(StringRef Filename, const DILineInfo &Info);
+  virtual void printFooter() {}
+
+private:
+  void printHeader(uint64_t Address);
+
+public:
+  PlainPrinterBase(raw_ostream &OS, raw_ostream &ES, PrinterConfig &Config)
+      : DIPrinter(), OS(OS), ES(ES), Config(Config) {}
+
+  void print(const Request &Request, const DILineInfo &Info) override;
+  void print(const Request &Request, const DIInliningInfo &Info) override;
+  void print(const Request &Request, const DIGlobal &Global) override;
+  void print(const Request &Request,
+             const std::vector<DILocal> &Locals) override;
+
+  void printInvalidCommand(const Request &Request,
+                           const ErrorInfoBase &ErrorInfo) override;
+
+  bool printError(const Request &Request, const ErrorInfoBase &ErrorInfo,
+                  StringRef ErrorBanner) override;
+};
+
+class LLVMPrinter : public PlainPrinterBase {
+private:
+  void printSimpleLocation(StringRef Filename, const DILineInfo &Info) override;
+  void printFooter() override;
+
+public:
+  LLVMPrinter(raw_ostream &OS, raw_ostream &ES, PrinterConfig &Config)
+      : PlainPrinterBase(OS, ES, Config) {}
+};
+
+class GNUPrinter : public PlainPrinterBase {
+private:
+  void printSimpleLocation(StringRef Filename, const DILineInfo &Info) override;
 
 public:
-  DIPrinter(raw_ostream &OS, bool PrintFunctionNames = true,
-            bool PrintPretty = false, int PrintSourceContext = 0,
-            bool Verbose = false, OutputStyle Style = OutputStyle::LLVM)
-      : OS(OS), PrintFunctionNames(PrintFunctionNames),
-        PrintPretty(PrintPretty), PrintSourceContext(PrintSourceContext),
-        Verbose(Verbose), Style(Style) {}
-
-  DIPrinter &operator<<(const DILineInfo &Info);
-  DIPrinter &operator<<(const DIInliningInfo &Info);
-  DIPrinter &operator<<(const DIGlobal &Global);
-  DIPrinter &operator<<(const DILocal &Local);
+  GNUPrinter(raw_ostream &OS, raw_ostream &ES, PrinterConfig &Config)
+      : PlainPrinterBase(OS, ES, Config) {}
 };
-}
-}
+} // namespace symbolize
+} // namespace llvm
 
 #endif

diff  --git a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
index 01dc31d849657..afed1bafee8be 100644
--- a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
@@ -30,9 +30,18 @@
 namespace llvm {
 namespace symbolize {
 
+void PlainPrinterBase::printHeader(uint64_t Address) {
+  if (Config.PrintAddress) {
+    OS << "0x";
+    OS.write_hex(Address);
+    StringRef Delimiter = Config.Pretty ? ": " : "\n";
+    OS << Delimiter;
+  }
+}
+
 // Prints source code around in the FileName the Line.
-void DIPrinter::printContext(const std::string &FileName, int64_t Line) {
-  if (PrintSourceContext <= 0)
+void PlainPrinterBase::printContext(StringRef FileName, int64_t Line) {
+  if (Config.SourceContextLines <= 0)
     return;
 
   ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
@@ -42,8 +51,8 @@ void DIPrinter::printContext(const std::string &FileName, int64_t Line) {
 
   std::unique_ptr<MemoryBuffer> Buf = std::move(BufOrErr.get());
   int64_t FirstLine =
-      std::max(static_cast<int64_t>(1), Line - PrintSourceContext / 2);
-  int64_t LastLine = FirstLine + PrintSourceContext;
+      std::max(static_cast<int64_t>(1), Line - Config.SourceContextLines / 2);
+  int64_t LastLine = FirstLine + Config.SourceContextLines;
   size_t MaxLineNumberWidth = std::ceil(std::log10(LastLine));
 
   for (line_iterator I = line_iterator(*Buf, false);
@@ -60,97 +69,145 @@ void DIPrinter::printContext(const std::string &FileName, int64_t Line) {
   }
 }
 
-void DIPrinter::print(const DILineInfo &Info, bool Inlined) {
-  if (PrintFunctionNames) {
-    std::string FunctionName = Info.FunctionName;
+void PlainPrinterBase::printFunctionName(StringRef FunctionName, bool Inlined) {
+  if (Config.PrintFunctions) {
     if (FunctionName == DILineInfo::BadString)
       FunctionName = DILineInfo::Addr2LineBadString;
-
-    StringRef Delimiter = PrintPretty ? " at " : "\n";
-    StringRef Prefix = (PrintPretty && Inlined) ? " (inlined by) " : "";
+    StringRef Delimiter = Config.Pretty ? " at " : "\n";
+    StringRef Prefix = (Config.Pretty && Inlined) ? " (inlined by) " : "";
     OS << Prefix << FunctionName << Delimiter;
   }
-  std::string Filename = Info.FileName;
-  if (Filename == DILineInfo::BadString)
-    Filename = DILineInfo::Addr2LineBadString;
-  if (!Verbose) {
-    OS << Filename << ":" << Info.Line;
-    if (Style == OutputStyle::LLVM)
-      OS << ":" << Info.Column;
-    else if (Style == OutputStyle::GNU && Info.Discriminator != 0)
-      OS << " (discriminator " << Info.Discriminator << ")";
-    OS << "\n";
-    printContext(Filename, Info.Line);
-    return;
-  }
-  OS << "  Filename: " << Filename << "\n";
+}
+
+void LLVMPrinter::printSimpleLocation(StringRef Filename,
+                                      const DILineInfo &Info) {
+  OS << Filename << ':' << Info.Line << ':' << Info.Column << '\n';
+  printContext(Filename, Info.Line);
+}
+
+void GNUPrinter::printSimpleLocation(StringRef Filename,
+                                     const DILineInfo &Info) {
+  OS << Filename << ':' << Info.Line;
+  if (Info.Discriminator)
+    OS << " (discriminator " << Info.Discriminator << ')';
+  OS << '\n';
+  printContext(Filename, Info.Line);
+}
+
+void PlainPrinterBase::printVerbose(StringRef Filename,
+                                    const DILineInfo &Info) {
+  OS << "  Filename: " << Filename << '\n';
   if (Info.StartLine) {
-    OS << "  Function start filename: " << Info.StartFileName << "\n";
-    OS << "  Function start line: " << Info.StartLine << "\n";
+    OS << "  Function start filename: " << Info.StartFileName << '\n';
+    OS << "  Function start line: " << Info.StartLine << '\n';
   }
-  OS << "  Line: " << Info.Line << "\n";
-  OS << "  Column: " << Info.Column << "\n";
+  OS << "  Line: " << Info.Line << '\n';
+  OS << "  Column: " << Info.Column << '\n';
   if (Info.Discriminator)
-    OS << "  Discriminator: " << Info.Discriminator << "\n";
+    OS << "  Discriminator: " << Info.Discriminator << '\n';
+}
+
+void LLVMPrinter::printFooter() { OS << '\n'; }
+
+void PlainPrinterBase::print(const DILineInfo &Info, bool Inlined) {
+  printFunctionName(Info.FunctionName, Inlined);
+  StringRef Filename = Info.FileName;
+  if (Filename == DILineInfo::BadString)
+    Filename = DILineInfo::Addr2LineBadString;
+  if (Config.Verbose)
+    printVerbose(Filename, Info);
+  else
+    printSimpleLocation(Filename, Info);
 }
 
-DIPrinter &DIPrinter::operator<<(const DILineInfo &Info) {
+void PlainPrinterBase::print(const Request &Request, const DILineInfo &Info) {
+  printHeader(Request.Address);
   print(Info, false);
-  return *this;
+  printFooter();
 }
 
-DIPrinter &DIPrinter::operator<<(const DIInliningInfo &Info) {
+void PlainPrinterBase::print(const Request &Request,
+                             const DIInliningInfo &Info) {
+  printHeader(Request.Address);
   uint32_t FramesNum = Info.getNumberOfFrames();
-  if (FramesNum == 0) {
+  if (FramesNum == 0)
     print(DILineInfo(), false);
-    return *this;
-  }
-  for (uint32_t i = 0; i < FramesNum; i++)
-    print(Info.getFrame(i), i > 0);
-  return *this;
+  else
+    for (uint32_t I = 0; I < FramesNum; ++I)
+      print(Info.getFrame(I), I > 0);
+  printFooter();
 }
 
-DIPrinter &DIPrinter::operator<<(const DIGlobal &Global) {
-  std::string Name = Global.Name;
+void PlainPrinterBase::print(const Request &Request, const DIGlobal &Global) {
+  printHeader(Request.Address);
+  StringRef Name = Global.Name;
   if (Name == DILineInfo::BadString)
     Name = DILineInfo::Addr2LineBadString;
   OS << Name << "\n";
   OS << Global.Start << " " << Global.Size << "\n";
-  return *this;
+  printFooter();
 }
 
-DIPrinter &DIPrinter::operator<<(const DILocal &Local) {
-  if (Local.FunctionName.empty())
-    OS << "??\n";
+void PlainPrinterBase::print(const Request &Request,
+                             const std::vector<DILocal> &Locals) {
+  printHeader(Request.Address);
+  if (Locals.empty())
+    OS << DILineInfo::Addr2LineBadString << '\n';
   else
-    OS << Local.FunctionName << '\n';
+    for (const DILocal &L : Locals) {
+      if (L.FunctionName.empty())
+        OS << DILineInfo::Addr2LineBadString;
+      else
+        OS << L.FunctionName;
+      OS << '\n';
 
-  if (Local.Name.empty())
-    OS << "??\n";
-  else
-    OS << Local.Name << '\n';
+      if (L.Name.empty())
+        OS << DILineInfo::Addr2LineBadString;
+      else
+        OS << L.Name;
+      OS << '\n';
 
-  if (Local.DeclFile.empty())
-    OS << "??";
-  else
-    OS << Local.DeclFile;
-  OS << ':' << Local.DeclLine << '\n';
+      if (L.DeclFile.empty())
+        OS << DILineInfo::Addr2LineBadString;
+      else
+        OS << L.DeclFile;
 
-  if (Local.FrameOffset)
-    OS << *Local.FrameOffset << ' ';
-  else
-    OS << "?? ";
+      OS << ':' << L.DeclLine << '\n';
 
-  if (Local.Size)
-    OS << *Local.Size << ' ';
-  else
-    OS << "?? ";
+      if (L.FrameOffset)
+        OS << *L.FrameOffset;
+      else
+        OS << DILineInfo::Addr2LineBadString;
+      OS << ' ';
 
-  if (Local.TagOffset)
-    OS << *Local.TagOffset << '\n';
-  else
-    OS << "??\n";
-  return *this;
+      if (L.Size)
+        OS << *L.Size;
+      else
+        OS << DILineInfo::Addr2LineBadString;
+      OS << ' ';
+
+      if (L.TagOffset)
+        OS << *L.TagOffset;
+      else
+        OS << DILineInfo::Addr2LineBadString;
+      OS << '\n';
+    }
+  printFooter();
+}
+
+void PlainPrinterBase::printInvalidCommand(const Request &Request,
+                                           const ErrorInfoBase &ErrorInfo) {
+  OS << ErrorInfo.message() << '\n';
+}
+
+bool PlainPrinterBase::printError(const Request &Request,
+                                  const ErrorInfoBase &ErrorInfo,
+                                  StringRef ErrorBanner) {
+  ES << ErrorBanner;
+  ErrorInfo.log(ES);
+  ES << '\n';
+  // Print an empty struct too.
+  return true;
 }
 
 } // end namespace symbolize

diff  --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
index 8734c2d740454..20617d376c140 100644
--- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
+++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
@@ -74,15 +74,29 @@ static cl::list<std::string> ClInputAddresses(cl::Positional,
                                               cl::desc("<input addresses>..."),
                                               cl::ZeroOrMore);
 
-template<typename T>
-static bool error(Expected<T> &ResOrErr) {
-  if (ResOrErr)
-    return false;
-  logAllUnhandledErrors(ResOrErr.takeError(), errs(),
-                        "LLVMSymbolizer: error reading file: ");
-  return true;
+template <typename T>
+static void print(const Request &Request, Expected<T> &ResOrErr,
+                  DIPrinter &Printer) {
+  if (ResOrErr) {
+    // No error, print the result.
+    Printer.print(Request, *ResOrErr);
+    return;
+  }
+
+  // Handle the error.
+  bool PrintEmpty = true;
+  handleAllErrors(std::move(ResOrErr.takeError()),
+                  [&](const ErrorInfoBase &EI) {
+                    PrintEmpty = Printer.printError(
+                        Request, EI, "LLVMSymbolizer: error reading file: ");
+                  });
+
+  if (PrintEmpty)
+    Printer.print(Request, T());
 }
 
+enum class OutputStyle { LLVM, GNU };
+
 enum class Command {
   Code,
   Data,
@@ -136,7 +150,7 @@ static bool parseCommand(StringRef BinaryName, bool IsAddr2Line,
 }
 
 static void symbolizeInput(const opt::InputArgList &Args, uint64_t AdjustVMA,
-                           bool IsAddr2Line, DIPrinter::OutputStyle OutputStyle,
+                           bool IsAddr2Line, OutputStyle OutputStyle,
                            StringRef InputString, LLVMSymbolizer &Symbolizer,
                            DIPrinter &Printer) {
   Command Cmd;
@@ -144,56 +158,46 @@ static void symbolizeInput(const opt::InputArgList &Args, uint64_t AdjustVMA,
   uint64_t Offset = 0;
   if (!parseCommand(Args.getLastArgValue(OPT_obj_EQ), IsAddr2Line,
                     StringRef(InputString), Cmd, ModuleName, Offset)) {
-    outs() << InputString << "\n";
+    Printer.printInvalidCommand(
+        {ModuleName, Offset},
+        StringError(InputString,
+                    std::make_error_code(std::errc::invalid_argument)));
     return;
   }
 
-  if (Args.hasArg(OPT_addresses)) {
-    outs() << "0x";
-    outs().write_hex(Offset);
-    StringRef Delimiter = Args.hasArg(OPT_pretty_print) ? ": " : "\n";
-    outs() << Delimiter;
-  }
-  Offset -= AdjustVMA;
+  uint64_t AdjustedOffset = Offset - AdjustVMA;
   if (Cmd == Command::Data) {
-    auto ResOrErr = Symbolizer.symbolizeData(
-        ModuleName, {Offset, object::SectionedAddress::UndefSection});
-    Printer << (error(ResOrErr) ? DIGlobal() : ResOrErr.get());
+    Expected<DIGlobal> ResOrErr = Symbolizer.symbolizeData(
+        ModuleName, {AdjustedOffset, object::SectionedAddress::UndefSection});
+    print({ModuleName, Offset}, ResOrErr, Printer);
   } else if (Cmd == Command::Frame) {
-    auto ResOrErr = Symbolizer.symbolizeFrame(
-        ModuleName, {Offset, object::SectionedAddress::UndefSection});
-    if (!error(ResOrErr)) {
-      for (DILocal Local : *ResOrErr)
-        Printer << Local;
-      if (ResOrErr->empty())
-        outs() << "??\n";
-    }
+    Expected<std::vector<DILocal>> ResOrErr = Symbolizer.symbolizeFrame(
+        ModuleName, {AdjustedOffset, object::SectionedAddress::UndefSection});
+    print({ModuleName, Offset}, ResOrErr, Printer);
   } else if (Args.hasFlag(OPT_inlines, OPT_no_inlines, !IsAddr2Line)) {
-    auto ResOrErr = Symbolizer.symbolizeInlinedCode(
-        ModuleName, {Offset, object::SectionedAddress::UndefSection});
-    Printer << (error(ResOrErr) ? DIInliningInfo() : ResOrErr.get());
-  } else if (OutputStyle == DIPrinter::OutputStyle::GNU) {
+    Expected<DIInliningInfo> ResOrErr = Symbolizer.symbolizeInlinedCode(
+        ModuleName, {AdjustedOffset, object::SectionedAddress::UndefSection});
+    print({ModuleName, Offset}, ResOrErr, Printer);
+  } else if (OutputStyle == OutputStyle::GNU) {
     // With PrintFunctions == FunctionNameKind::LinkageName (default)
     // and UseSymbolTable == true (also default), Symbolizer.symbolizeCode()
     // may override the name of an inlined function with the name of the topmost
     // caller function in the inlining chain. This contradicts the existing
     // behavior of addr2line. Symbolizer.symbolizeInlinedCode() overrides only
     // the topmost function, which suits our needs better.
-    auto ResOrErr = Symbolizer.symbolizeInlinedCode(
-        ModuleName, {Offset, object::SectionedAddress::UndefSection});
-    if (!ResOrErr || ResOrErr->getNumberOfFrames() == 0) {
-      error(ResOrErr);
-      Printer << DILineInfo();
-    } else {
-      Printer << ResOrErr->getFrame(0);
-    }
+    Expected<DIInliningInfo> ResOrErr = Symbolizer.symbolizeInlinedCode(
+        ModuleName, {AdjustedOffset, object::SectionedAddress::UndefSection});
+    Expected<DILineInfo> Res0OrErr =
+        !ResOrErr
+            ? Expected<DILineInfo>(ResOrErr.takeError())
+            : ((ResOrErr->getNumberOfFrames() == 0) ? DILineInfo()
+                                                    : ResOrErr->getFrame(0));
+    print({ModuleName, Offset}, Res0OrErr, Printer);
   } else {
-    auto ResOrErr = Symbolizer.symbolizeCode(
-        ModuleName, {Offset, object::SectionedAddress::UndefSection});
-    Printer << (error(ResOrErr) ? DILineInfo() : ResOrErr.get());
+    Expected<DILineInfo> ResOrErr = Symbolizer.symbolizeCode(
+        ModuleName, {AdjustedOffset, object::SectionedAddress::UndefSection});
+    print({ModuleName, Offset}, ResOrErr, Printer);
   }
-  if (OutputStyle == DIPrinter::OutputStyle::LLVM)
-    outs() << "\n";
 }
 
 static void printHelp(StringRef ToolName, const SymbolizerOptTable &Tbl,
@@ -273,7 +277,7 @@ int main(int argc, char **argv) {
 
   LLVMSymbolizer::Options Opts;
   uint64_t AdjustVMA;
-  unsigned SourceContextLines;
+  PrinterConfig Config;
   parseIntArg(Args, OPT_adjust_vma_EQ, AdjustVMA);
   if (const opt::Arg *A = Args.getLastArg(OPT_basenames, OPT_relativenames)) {
     Opts.PathStyle =
@@ -290,7 +294,8 @@ int main(int argc, char **argv) {
   Opts.FallbackDebugPath =
       Args.getLastArgValue(OPT_fallback_debug_path_EQ).str();
   Opts.PrintFunctions = decideHowToPrintFunctions(Args, IsAddr2Line);
-  parseIntArg(Args, OPT_print_source_context_lines_EQ, SourceContextLines);
+  parseIntArg(Args, OPT_print_source_context_lines_EQ,
+              Config.SourceContextLines);
   Opts.RelativeAddresses = Args.hasArg(OPT_relative_address);
   Opts.UntagAddresses =
       Args.hasFlag(OPT_untag_addresses, OPT_no_untag_addresses, !IsAddr2Line);
@@ -302,6 +307,10 @@ int main(int argc, char **argv) {
   }
 #endif
   Opts.UseSymbolTable = true;
+  Config.PrintAddress = Args.hasArg(OPT_addresses);
+  Config.PrintFunctions = Opts.PrintFunctions != FunctionNameKind::None;
+  Config.Pretty = Args.hasArg(OPT_pretty_print);
+  Config.Verbose = Args.hasArg(OPT_verbose);
 
   for (const opt::Arg *A : Args.filtered(OPT_dsym_hint_EQ)) {
     StringRef Hint(A->getValue());
@@ -313,18 +322,18 @@ int main(int argc, char **argv) {
     }
   }
 
-  auto OutputStyle =
-      IsAddr2Line ? DIPrinter::OutputStyle::GNU : DIPrinter::OutputStyle::LLVM;
+  auto OutputStyle = IsAddr2Line ? OutputStyle::GNU : OutputStyle::LLVM;
   if (const opt::Arg *A = Args.getLastArg(OPT_output_style_EQ)) {
-    OutputStyle = strcmp(A->getValue(), "GNU") == 0
-                      ? DIPrinter::OutputStyle::GNU
-                      : DIPrinter::OutputStyle::LLVM;
+    OutputStyle = strcmp(A->getValue(), "GNU") == 0 ? OutputStyle::GNU
+                                                    : OutputStyle::LLVM;
   }
 
   LLVMSymbolizer Symbolizer(Opts);
-  DIPrinter Printer(outs(), Opts.PrintFunctions != FunctionNameKind::None,
-                    Args.hasArg(OPT_pretty_print), SourceContextLines,
-                    Args.hasArg(OPT_verbose), OutputStyle);
+  std::unique_ptr<DIPrinter> Printer;
+  if (OutputStyle == OutputStyle::GNU)
+    Printer = std::make_unique<GNUPrinter>(outs(), errs(), Config);
+  else
+    Printer = std::make_unique<LLVMPrinter>(outs(), errs(), Config);
 
   std::vector<std::string> InputAddresses = Args.getAllArgValues(OPT_INPUT);
   if (InputAddresses.empty()) {
@@ -337,13 +346,13 @@ int main(int argc, char **argv) {
       llvm::erase_if(StrippedInputString,
                      [](char c) { return c == '\r' || c == '\n'; });
       symbolizeInput(Args, AdjustVMA, IsAddr2Line, OutputStyle,
-                     StrippedInputString, Symbolizer, Printer);
+                     StrippedInputString, Symbolizer, *Printer);
       outs().flush();
     }
   } else {
     for (StringRef Address : InputAddresses)
       symbolizeInput(Args, AdjustVMA, IsAddr2Line, OutputStyle, Address,
-                     Symbolizer, Printer);
+                     Symbolizer, *Printer);
   }
 
   return 0;


        


More information about the llvm-commits mailing list