Update the MemoryBuffer API to use ErrorOr.
[oota-llvm.git] / tools / llvm-symbolizer / LLVMSymbolize.cpp
index 7ffb1a13c59cbc11480632f81a0a0331afdb022d..c1d39efc1b81bada0fe776e3f2eac846718fbcea 100644 (file)
@@ -19,6 +19,7 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Compression.h"
 #include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Errc.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 namespace llvm {
 namespace symbolize {
 
-static bool error(error_code ec) {
+static bool error(std::error_code ec) {
   if (!ec)
     return false;
   errs() << "LLVMSymbolizer: error reading file: " << ec.message() << ".\n";
   return true;
 }
 
-static uint32_t
-getDILineInfoSpecifierFlags(const LLVMSymbolizer::Options &Opts) {
-  uint32_t Flags = llvm::DILineInfoSpecifier::FileLineInfo |
-                   llvm::DILineInfoSpecifier::AbsoluteFilePath;
-  if (Opts.PrintFunctions)
-    Flags |= llvm::DILineInfoSpecifier::FunctionName;
-  return Flags;
+static DILineInfoSpecifier
+getDILineInfoSpecifier(const LLVMSymbolizer::Options &Opts) {
+  return DILineInfoSpecifier(
+      DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
+      Opts.PrintFunctions);
 }
 
 ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
@@ -115,10 +114,10 @@ DILineInfo ModuleInfo::symbolizeCode(
   DILineInfo LineInfo;
   if (DebugInfoContext) {
     LineInfo = DebugInfoContext->getLineInfoForAddress(
-        ModuleOffset, getDILineInfoSpecifierFlags(Opts));
+        ModuleOffset, getDILineInfoSpecifier(Opts));
   }
   // Override function name from symbol table if necessary.
-  if (Opts.PrintFunctions && Opts.UseSymbolTable) {
+  if (Opts.PrintFunctions != FunctionNameKind::None && Opts.UseSymbolTable) {
     std::string FunctionName;
     uint64_t Start, Size;
     if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset,
@@ -134,14 +133,14 @@ DIInliningInfo ModuleInfo::symbolizeInlinedCode(
   DIInliningInfo InlinedContext;
   if (DebugInfoContext) {
     InlinedContext = DebugInfoContext->getInliningInfoForAddress(
-        ModuleOffset, getDILineInfoSpecifierFlags(Opts));
+        ModuleOffset, getDILineInfoSpecifier(Opts));
   }
   // Make sure there is at least one frame in context.
   if (InlinedContext.getNumberOfFrames() == 0) {
     InlinedContext.addFrame(DILineInfo());
   }
   // Override the function name in lower frame with name from symbol table.
-  if (Opts.PrintFunctions && Opts.UseSymbolTable) {
+  if (Opts.PrintFunctions != FunctionNameKind::None && Opts.UseSymbolTable) {
     DIInliningInfo PatchedInlinedContext;
     for (uint32_t i = 0, n = InlinedContext.getNumberOfFrames(); i < n; i++) {
       DILineInfo LineInfo = InlinedContext.getFrame(i);
@@ -171,7 +170,7 @@ const char LLVMSymbolizer::kBadString[] = "??";
 std::string LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
                                           uint64_t ModuleOffset) {
   ModuleInfo *Info = getOrCreateModuleInfo(ModuleName);
-  if (Info == 0)
+  if (!Info)
     return printDILineInfo(DILineInfo());
   if (Opts.PrintInlining) {
     DIInliningInfo InlinedContext =
@@ -207,7 +206,6 @@ std::string LLVMSymbolizer::symbolizeData(const std::string &ModuleName,
 
 void LLVMSymbolizer::flush() {
   DeleteContainerSeconds(Modules);
-  DeleteContainerPointers(ParsedBinariesAndObjects);
   BinaryForPath.clear();
   ObjectFileForArch.clear();
 }
@@ -222,10 +220,11 @@ static std::string getDarwinDWARFResourceForPath(const std::string &Path) {
 }
 
 static bool checkFileCRC(StringRef Path, uint32_t CRCHash) {
-  std::unique_ptr<MemoryBuffer> MB;
-  if (MemoryBuffer::getFileOrSTDIN(Path, MB))
+  ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
+      MemoryBuffer::getFileOrSTDIN(Path);
+  if (!MB)
     return false;
-  return !zlib::isAvailable() || CRCHash == zlib::crc32(MB->getBuffer());
+  return !zlib::isAvailable() || CRCHash == zlib::crc32(MB.get()->getBuffer());
 }
 
 static bool findDebugBinary(const std::string &OrigPath,
@@ -233,7 +232,7 @@ static bool findDebugBinary(const std::string &OrigPath,
                             std::string &Result) {
   std::string OrigRealPath = OrigPath;
 #if defined(HAVE_REALPATH)
-  if (char *RP = realpath(OrigPath.c_str(), NULL)) {
+  if (char *RP = realpath(OrigPath.c_str(), nullptr)) {
     OrigRealPath = RP;
     free(RP);
   }
@@ -299,28 +298,28 @@ LLVMSymbolizer::getOrCreateBinary(const std::string &Path) {
   BinaryMapTy::iterator I = BinaryForPath.find(Path);
   if (I != BinaryForPath.end())
     return I->second;
-  Binary *Bin = 0;
-  Binary *DbgBin = 0;
+  Binary *Bin = nullptr;
+  Binary *DbgBin = nullptr;
   ErrorOr<Binary *> BinaryOrErr = createBinary(Path);
   if (!error(BinaryOrErr.getError())) {
     std::unique_ptr<Binary> ParsedBinary(BinaryOrErr.get());
     // Check if it's a universal binary.
-    Bin = ParsedBinary.release();
-    ParsedBinariesAndObjects.push_back(Bin);
+    Bin = ParsedBinary.get();
+    ParsedBinariesAndObjects.push_back(std::move(ParsedBinary));
     if (Bin->isMachO() || Bin->isMachOUniversalBinary()) {
       // On Darwin we may find DWARF in separate object file in
       // resource directory.
       const std::string &ResourcePath =
           getDarwinDWARFResourceForPath(Path);
       BinaryOrErr = createBinary(ResourcePath);
-      error_code EC = BinaryOrErr.getError();
+      std::error_code EC = BinaryOrErr.getError();
       if (EC != errc::no_such_file_or_directory && !error(EC)) {
         DbgBin = BinaryOrErr.get();
-        ParsedBinariesAndObjects.push_back(DbgBin);
+        ParsedBinariesAndObjects.push_back(std::unique_ptr<Binary>(DbgBin));
       }
     }
     // Try to locate the debug binary using .gnu_debuglink section.
-    if (DbgBin == 0) {
+    if (!DbgBin) {
       std::string DebuglinkName;
       uint32_t CRCHash;
       std::string DebugBinaryPath;
@@ -329,12 +328,12 @@ LLVMSymbolizer::getOrCreateBinary(const std::string &Path) {
         BinaryOrErr = createBinary(DebugBinaryPath);
         if (!error(BinaryOrErr.getError())) {
           DbgBin = BinaryOrErr.get();
-          ParsedBinariesAndObjects.push_back(DbgBin);
+          ParsedBinariesAndObjects.push_back(std::unique_ptr<Binary>(DbgBin));
         }
       }
     }
   }
-  if (DbgBin == 0)
+  if (!DbgBin)
     DbgBin = Bin;
   BinaryPair Res = std::make_pair(Bin, DbgBin);
   BinaryForPath[Path] = Res;
@@ -343,18 +342,19 @@ LLVMSymbolizer::getOrCreateBinary(const std::string &Path) {
 
 ObjectFile *
 LLVMSymbolizer::getObjectFileFromBinary(Binary *Bin, const std::string &ArchName) {
-  if (Bin == 0)
-    return 0;
-  ObjectFile *Res = 0;
+  if (!Bin)
+    return nullptr;
+  ObjectFile *Res = nullptr;
   if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(Bin)) {
     ObjectFileForArchMapTy::iterator I = ObjectFileForArch.find(
         std::make_pair(UB, ArchName));
     if (I != ObjectFileForArch.end())
       return I->second;
-    std::unique_ptr<ObjectFile> ParsedObj;
-    if (!UB->getObjectForArch(Triple(ArchName).getArch(), ParsedObj)) {
-      Res = ParsedObj.release();
-      ParsedBinariesAndObjects.push_back(Res);
+    ErrorOr<std::unique_ptr<ObjectFile>> ParsedObj =
+        UB->getObjectForArch(Triple(ArchName).getArch());
+    if (ParsedObj) {
+      Res = ParsedObj.get().get();
+      ParsedBinariesAndObjects.push_back(std::move(ParsedObj.get()));
     }
     ObjectFileForArch[std::make_pair(UB, ArchName)] = Res;
   } else if (Bin->isObject()) {
@@ -383,10 +383,10 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) {
   ObjectFile *Obj = getObjectFileFromBinary(Binaries.first, ArchName);
   ObjectFile *DbgObj = getObjectFileFromBinary(Binaries.second, ArchName);
 
-  if (Obj == 0) {
+  if (!Obj) {
     // Failed to find valid object file.
-    Modules.insert(make_pair(ModuleName, (ModuleInfo *)0));
-    return 0;
+    Modules.insert(make_pair(ModuleName, (ModuleInfo *)nullptr));
+    return nullptr;
   }
   DIContext *Context = DIContext::getDWARFContext(DbgObj);
   assert(Context);
@@ -400,7 +400,7 @@ std::string LLVMSymbolizer::printDILineInfo(DILineInfo LineInfo) const {
   // cannot fetch. We replace it to "??" to make our output closer to addr2line.
   static const std::string kDILineInfoBadString = "<invalid>";
   std::stringstream Result;
-  if (Opts.PrintFunctions) {
+  if (Opts.PrintFunctions != FunctionNameKind::None) {
     std::string FunctionName = LineInfo.FunctionName;
     if (FunctionName == kDILineInfoBadString)
       FunctionName = kBadString;
@@ -428,7 +428,7 @@ std::string LLVMSymbolizer::DemangleName(const std::string &Name) {
   if (Name.substr(0, 2) != "_Z")
     return Name;
   int status = 0;
-  char *DemangledName = __cxa_demangle(Name.c_str(), 0, 0, &status);
+  char *DemangledName = __cxa_demangle(Name.c_str(), nullptr, nullptr, &status);
   if (status != 0)
     return Name;
   std::string Result = DemangledName;