Changes For Bug 352
[oota-llvm.git] / tools / llvm-nm / llvm-nm.cpp
index e98f6550d243da471d793fa4f2349ab9cca3f1e0..1a2b40e9c9b012547e57489e759ad277064ff9e8 100644 (file)
@@ -1,4 +1,11 @@
 //===-- llvm-nm.cpp - Symbol table dumping utility for llvm ---------------===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
 //
 // This program is a utility that works like traditional Unix "nm",
 // that is, it prints out the names of symbols in a bytecode file,
 //
 //===----------------------------------------------------------------------===//
 
-#include "Support/CommandLine.h"
-#include "llvm/Bytecode/Reader.h"
-#include "llvm/GlobalValue.h"
 #include "llvm/Module.h"
+#include "llvm/Bytecode/Reader.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/System/Signals.h"
 #include <cctype>
+#include <cerrno>
+#include <cstring>
+#include <iostream>
+
+using namespace llvm;
 
 namespace {
   enum OutputFormatTy { bsd, sysv, posix };
@@ -22,7 +35,8 @@ namespace {
        cl::desc("Specify output format"),
          cl::values(clEnumVal(bsd,   "BSD format"),
                     clEnumVal(sysv,  "System V format"),
-                    clEnumVal(posix, "POSIX.2 format"), 0), cl::init(bsd));
+                    clEnumVal(posix, "POSIX.2 format"), 
+                    clEnumValEnd), cl::init(bsd));
   cl::alias OutputFormat2("f", cl::desc("Alias for --format"),
                           cl::aliasopt(OutputFormat));
 
@@ -88,31 +102,56 @@ void DumpSymbolNameForGlobalValue (GlobalValue &GV) {
 }
 
 void DumpSymbolNamesFromModule (Module *M) {
+  const std::string &Filename = M->getModuleIdentifier ();
+  if (OutputFormat == posix && MultipleFiles) {
+    std::cout << Filename << ":\n";
+  } else if (OutputFormat == bsd && MultipleFiles) {
+    std::cout << "\n" << Filename << ":\n";
+  } else if (OutputFormat == sysv) {
+    std::cout << "\n\nSymbols from " << Filename << ":\n\n"
+              << "Name                  Value   Class        Type"
+              << "         Size   Line  Section\n";
+  }
   std::for_each (M->begin (), M->end (), DumpSymbolNameForGlobalValue);
   std::for_each (M->gbegin (), M->gend (), DumpSymbolNameForGlobalValue);
 }
 
 void DumpSymbolNamesFromFile (std::string &Filename) {
   std::string ErrorMessage;
-  Module *Result = ParseBytecodeFile(Filename, &ErrorMessage);
-  if (Result) {
-    if (OutputFormat == posix && MultipleFiles) {
-      std::cout << Filename << ":\n";
-    } else if (OutputFormat == bsd && MultipleFiles) {
-      std::cout << "\n" << Filename << ":\n";
-    } else if (OutputFormat == sysv) {
-      std::cout << "\n\nSymbols from " << Filename << ":\n\n"
-                << "Name                  Value   Class        Type"
-                << "         Size   Line  Section\n";
+  if (Filename != "-" && !FileOpenable (Filename)) {
+    std::cerr << ToolName << ": " << Filename << ": " << strerror (errno)
+              << "\n";
+    return;
+  }
+  // Note: Currently we do not support reading an archive from stdin.
+  if (Filename == "-" || IsBytecode (Filename)) {
+    Module *Result = ParseBytecodeFile(Filename, &ErrorMessage);
+    if (Result) {
+      DumpSymbolNamesFromModule (Result);
+    } else {
+      std::cerr << ToolName << ": " << Filename << ": " << ErrorMessage << "\n";
+      return;
     }
-    DumpSymbolNamesFromModule (Result);
+  } else if (IsArchive (Filename)) {
+    std::vector<Module *> Modules;
+    if (ReadArchiveFile (Filename, Modules, &ErrorMessage)) {
+      std::cerr << ToolName << ": " << Filename << ": "
+                << ErrorMessage << "\n";
+      return;
+    }
+    MultipleFiles = true;
+    std::for_each (Modules.begin (), Modules.end (), DumpSymbolNamesFromModule);
   } else {
-    std::cerr << ToolName << ": " << Filename << ": " << ErrorMessage << "\n";
+    std::cerr << ToolName << ": " << Filename << ": "
+              << "unrecognizable file type\n";
+    return;
   }
 }
 
 int main(int argc, char **argv) {
   cl::ParseCommandLineOptions(argc, argv, " llvm symbol table dumper\n");
+  sys::PrintStackTraceOnErrorSignal();
+
   ToolName = argv[0];
   if (BSDFormat) OutputFormat = bsd;
   if (POSIXFormat) OutputFormat = posix;