llvm-as.cpp revision 193323
1//===--- llvm-as.cpp - The low-level LLVM assembler -----------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This utility may be invoked in the following manner: 11// llvm-as --help - Output information about command line switches 12// llvm-as [options] - Read LLVM asm from stdin, write bitcode to stdout 13// llvm-as [options] x.ll - Read LLVM asm from the x.ll file, write bitcode 14// to the x.bc file. 15// 16//===----------------------------------------------------------------------===// 17 18#include "llvm/Module.h" 19#include "llvm/Assembly/Parser.h" 20#include "llvm/Analysis/Verifier.h" 21#include "llvm/Bitcode/ReaderWriter.h" 22#include "llvm/Support/CommandLine.h" 23#include "llvm/Support/ManagedStatic.h" 24#include "llvm/Support/PrettyStackTrace.h" 25#include "llvm/Support/Streams.h" 26#include "llvm/Support/SystemUtils.h" 27#include "llvm/Support/raw_ostream.h" 28#include "llvm/System/Signals.h" 29#include <fstream> 30#include <iostream> 31#include <memory> 32using namespace llvm; 33 34static cl::opt<std::string> 35InputFilename(cl::Positional, cl::desc("<input .llvm file>"), cl::init("-")); 36 37static cl::opt<std::string> 38OutputFilename("o", cl::desc("Override output filename"), 39 cl::value_desc("filename")); 40 41static cl::opt<bool> 42Force("f", cl::desc("Overwrite output files")); 43 44static cl::opt<bool> 45DisableOutput("disable-output", cl::desc("Disable output"), cl::init(false)); 46 47static cl::opt<bool> 48DumpAsm("d", cl::desc("Print assembly as parsed"), cl::Hidden); 49 50static cl::opt<bool> 51DisableVerify("disable-verify", cl::Hidden, 52 cl::desc("Do not run verifier on input LLVM (dangerous!)")); 53 54int main(int argc, char **argv) { 55 // Print a stack trace if we signal out. 56 sys::PrintStackTraceOnErrorSignal(); 57 PrettyStackTraceProgram X(argc, argv); 58 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 59 cl::ParseCommandLineOptions(argc, argv, "llvm .ll -> .bc assembler\n"); 60 61 int exitCode = 0; 62 std::ostream *Out = 0; 63 try { 64 // Parse the file now... 65 ParseError Err; 66 std::auto_ptr<Module> M(ParseAssemblyFile(InputFilename, Err)); 67 if (M.get() == 0) { 68 Err.PrintError(argv[0], errs()); 69 return 1; 70 } 71 72 if (!DisableVerify) { 73 std::string Err; 74 if (verifyModule(*M.get(), ReturnStatusAction, &Err)) { 75 cerr << argv[0] 76 << ": assembly parsed, but does not verify as correct!\n"; 77 cerr << Err; 78 return 1; 79 } 80 } 81 82 if (DumpAsm) cerr << "Here's the assembly:\n" << *M.get(); 83 84 if (OutputFilename != "") { // Specified an output filename? 85 if (OutputFilename != "-") { // Not stdout? 86 if (!Force && std::ifstream(OutputFilename.c_str())) { 87 // If force is not specified, make sure not to overwrite a file! 88 cerr << argv[0] << ": error opening '" << OutputFilename 89 << "': file exists!\n" 90 << "Use -f command line argument to force output\n"; 91 return 1; 92 } 93 Out = new std::ofstream(OutputFilename.c_str(), std::ios::out | 94 std::ios::trunc | std::ios::binary); 95 } else { // Specified stdout 96 // FIXME: cout is not binary! 97 Out = &std::cout; 98 } 99 } else { 100 if (InputFilename == "-") { 101 OutputFilename = "-"; 102 Out = &std::cout; 103 } else { 104 std::string IFN = InputFilename; 105 int Len = IFN.length(); 106 if (IFN[Len-3] == '.' && IFN[Len-2] == 'l' && IFN[Len-1] == 'l') { 107 // Source ends in .ll 108 OutputFilename = std::string(IFN.begin(), IFN.end()-3); 109 } else { 110 OutputFilename = IFN; // Append a .bc to it 111 } 112 OutputFilename += ".bc"; 113 114 if (!Force && std::ifstream(OutputFilename.c_str())) { 115 // If force is not specified, make sure not to overwrite a file! 116 cerr << argv[0] << ": error opening '" << OutputFilename 117 << "': file exists!\n" 118 << "Use -f command line argument to force output\n"; 119 return 1; 120 } 121 122 Out = new std::ofstream(OutputFilename.c_str(), std::ios::out | 123 std::ios::trunc | std::ios::binary); 124 // Make sure that the Out file gets unlinked from the disk if we get a 125 // SIGINT 126 sys::RemoveFileOnSignal(sys::Path(OutputFilename)); 127 } 128 } 129 130 if (!Out->good()) { 131 cerr << argv[0] << ": error opening " << OutputFilename << "!\n"; 132 return 1; 133 } 134 135 if (!DisableOutput) 136 if (Force || !CheckBitcodeOutputToConsole(Out,true)) 137 WriteBitcodeToFile(M.get(), *Out); 138 } catch (const std::string& msg) { 139 cerr << argv[0] << ": " << msg << "\n"; 140 exitCode = 1; 141 } catch (...) { 142 cerr << argv[0] << ": Unexpected unknown exception occurred.\n"; 143 exitCode = 1; 144 } 145 146 if (Out != &std::cout) delete Out; 147 return exitCode; 148} 149 150