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