blob: 22ab0b049c1edf15e85baabc68f48be10cea4f3c [file] [log] [blame]
Reid Spencerdb5c86d2004-06-07 17:53:43 +00001//===-- llvm-dis.cpp - The low-level LLVM disassembler --------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This utility may be invoked in the following manner:
11// llvm-dis [options] - Read LLVM bytecode from stdin, write asm to stdout
12// llvm-dis [options] x.bc - Read LLVM bytecode from the x.bc file, write asm
13// to the x.ll file.
14// Options:
15// --help - Output information about command line switches
16// -c - Print C code instead of LLVM assembly
17//
18//===----------------------------------------------------------------------===//
19
20#include "llvm/Bytecode/Analyzer.h"
21#include "Support/CommandLine.h"
22#include "llvm/System/Signals.h"
23#include <fstream>
24#include <iostream>
25
26using namespace llvm;
27
28static cl::opt<std::string>
29 InputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-"));
30
31static cl::opt<std::string>
32 OutputFilename("o", cl::desc("Override output filename"),
33 cl::value_desc("filename"));
34
35static cl::opt<bool> Force ("f", cl::desc("Overwrite output files"));
36static cl::opt<bool> Detailed ("d", cl::desc("Detailed output"));
37
38int
39main(int argc, char **argv)
40{
41 cl::ParseCommandLineOptions(argc, argv,
42 " llvm-abcd Analysis of ByteCode Dumper\n");
43
44 PrintStackTraceOnErrorSignal();
45
46 std::ostream* Out = &std::cout; // Default to printing to stdout...
47 std::istream* In = &std::cin; // Default to reading stdin
48 std::string ErrorMessage;
49 BytecodeAnalysis bca;
50
51 /// Analyze the bytecode file
52 AnalyzeBytecodeFile(InputFilename, bca, &ErrorMessage);
53
54 // If there was an error, print it and stop.
55 if ( ErrorMessage.size() ) {
56 std::cerr << argv[0] << ": " << ErrorMessage << "\n";
57 return 1;
58 }
59
60 // Figure out where the output is going
61 if (OutputFilename != "") { // Specified an output filename?
62 if (OutputFilename != "-") { // Not stdout?
63 if (!Force && std::ifstream(OutputFilename.c_str())) {
64 // If force is not specified, make sure not to overwrite a file!
65 std::cerr << argv[0] << ": error opening '" << OutputFilename
66 << "': file exists! Sending to standard output.\n";
67 } else {
68 Out = new std::ofstream(OutputFilename.c_str());
69 }
70 }
71 } else {
72 if (InputFilename == "-") {
73 OutputFilename = "-";
74 } else {
75 std::string IFN = InputFilename;
76 int Len = IFN.length();
77 if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
78 // Source ends in .bc
79 OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".abc";
80 } else {
81 OutputFilename = IFN+".abc";
82 }
83
84 if (!Force && std::ifstream(OutputFilename.c_str())) {
85 // If force is not specified, make sure not to overwrite a file!
86 std::cerr << argv[0] << ": error opening '" << OutputFilename
87 << "': file exists! Sending to standard output.\n";
88 } else {
89 Out = new std::ofstream(OutputFilename.c_str());
90
91 // Make sure that the Out file gets unlinked from the disk if we get a
92 // SIGINT
93 RemoveFileOnSignal(OutputFilename);
94 }
95 }
96 }
97
98 if (!Out->good()) {
99 std::cerr << argv[0] << ": error opening " << OutputFilename
100 << ": sending to stdout instead!\n";
101 Out = &std::cout;
102 }
103
104 // All that abcd does is write the gathered statistics to the output
105 bca.dumpBytecode = true;
106 PrintBytecodeAnalysis(bca,*Out);
107
108 if (Out != &std::cout) {
109 ((std::ofstream*)Out)->close();
110 delete Out;
111 }
112 return 0;
113}
114
115// vim: sw=2