llvm-as.cpp revision 234353
189857Sobrien//===--- llvm-as.cpp - The low-level LLVM assembler -----------------------===// 289857Sobrien// 389857Sobrien// The LLVM Compiler Infrastructure 489857Sobrien// 589857Sobrien// This file is distributed under the University of Illinois Open Source 689857Sobrien// License. See LICENSE.TXT for details. 789857Sobrien// 889857Sobrien//===----------------------------------------------------------------------===// 989857Sobrien// 1089857Sobrien// This utility may be invoked in the following manner: 1189857Sobrien// llvm-as --help - Output information about command line switches 1289857Sobrien// llvm-as [options] - Read LLVM asm from stdin, write bitcode to stdout 1389857Sobrien// llvm-as [options] x.ll - Read LLVM asm from the x.ll file, write bitcode 1489857Sobrien// to the x.bc file. 1589857Sobrien// 1689857Sobrien//===----------------------------------------------------------------------===// 1789857Sobrien 1889857Sobrien#include "llvm/LLVMContext.h" 1989857Sobrien#include "llvm/Module.h" 20218822Sdim#include "llvm/Assembly/Parser.h" 21218822Sdim#include "llvm/Analysis/Verifier.h" 2289857Sobrien#include "llvm/Bitcode/ReaderWriter.h" 2389857Sobrien#include "llvm/Support/CommandLine.h" 2489857Sobrien#include "llvm/Support/ManagedStatic.h" 2589857Sobrien#include "llvm/Support/PrettyStackTrace.h" 2689857Sobrien#include "llvm/Support/SourceMgr.h" 2789857Sobrien#include "llvm/Support/SystemUtils.h" 2889857Sobrien#include "llvm/Support/ToolOutputFile.h" 2989857Sobrien#include "llvm/Support/Signals.h" 3089857Sobrien#include <memory> 3189857Sobrienusing namespace llvm; 3289857Sobrien 3389857Sobrienstatic cl::opt<std::string> 3489857SobrienInputFilename(cl::Positional, cl::desc("<input .llvm file>"), cl::init("-")); 3589857Sobrien 3689857Sobrienstatic cl::opt<std::string> 3789857SobrienOutputFilename("o", cl::desc("Override output filename"), 3889857Sobrien cl::value_desc("filename")); 3989857Sobrien 4089857Sobrienstatic cl::opt<bool> 4189857SobrienForce("f", cl::desc("Enable binary output on terminals")); 4289857Sobrien 4389857Sobrienstatic cl::opt<bool> 4489857SobrienDisableOutput("disable-output", cl::desc("Disable output"), cl::init(false)); 4589857Sobrien 4689857Sobrienstatic cl::opt<bool> 4789857SobrienDumpAsm("d", cl::desc("Print assembly as parsed"), cl::Hidden); 4889857Sobrien 4989857Sobrienstatic cl::opt<bool> 5089857SobrienDisableVerify("disable-verify", cl::Hidden, 5189857Sobrien cl::desc("Do not run verifier on input LLVM (dangerous!)")); 5289857Sobrien 5389857Sobrienstatic void WriteOutputFile(const Module *M) { 5489857Sobrien // Infer the output filename if needed. 5589857Sobrien if (OutputFilename.empty()) { 5689857Sobrien if (InputFilename == "-") { 5789857Sobrien OutputFilename = "-"; 5889857Sobrien } else { 5989857Sobrien std::string IFN = InputFilename; 6089857Sobrien int Len = IFN.length(); 6189857Sobrien if (IFN[Len-3] == '.' && IFN[Len-2] == 'l' && IFN[Len-1] == 'l') { 6289857Sobrien // Source ends in .ll 6389857Sobrien OutputFilename = std::string(IFN.begin(), IFN.end()-3); 6489857Sobrien } else { 6589857Sobrien OutputFilename = IFN; // Append a .bc to it 6689857Sobrien } 6789857Sobrien OutputFilename += ".bc"; 6889857Sobrien } 6989857Sobrien } 7089857Sobrien 7189857Sobrien std::string ErrorInfo; 7289857Sobrien OwningPtr<tool_output_file> Out 7389857Sobrien (new tool_output_file(OutputFilename.c_str(), ErrorInfo, 7489857Sobrien raw_fd_ostream::F_Binary)); 7589857Sobrien if (!ErrorInfo.empty()) { 7689857Sobrien errs() << ErrorInfo << '\n'; 7789857Sobrien exit(1); 7889857Sobrien } 7989857Sobrien 8089857Sobrien if (Force || !CheckBitcodeOutputToConsole(Out->os(), true)) 8189857Sobrien WriteBitcodeToFile(M, Out->os()); 8289857Sobrien 8389857Sobrien // Declare success. 8489857Sobrien Out->keep(); 8589857Sobrien} 8689857Sobrien 8789857Sobrienint main(int argc, char **argv) { 8889857Sobrien // Print a stack trace if we signal out. 8989857Sobrien sys::PrintStackTraceOnErrorSignal(); 9089857Sobrien PrettyStackTraceProgram X(argc, argv); 9189857Sobrien LLVMContext &Context = getGlobalContext(); 9289857Sobrien llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 9389857Sobrien cl::ParseCommandLineOptions(argc, argv, "llvm .ll -> .bc assembler\n"); 9489857Sobrien 9589857Sobrien // Parse the file now... 9689857Sobrien SMDiagnostic Err; 9789857Sobrien std::auto_ptr<Module> M(ParseAssemblyFile(InputFilename, Err, Context)); 9889857Sobrien if (M.get() == 0) { 9989857Sobrien Err.print(argv[0], errs()); 10089857Sobrien return 1; 10189857Sobrien } 10289857Sobrien 10389857Sobrien if (!DisableVerify) { 10489857Sobrien std::string Err; 10589857Sobrien if (verifyModule(*M.get(), ReturnStatusAction, &Err)) { 10689857Sobrien errs() << argv[0] 10789857Sobrien << ": assembly parsed, but does not verify as correct!\n"; 10889857Sobrien errs() << Err; 10989857Sobrien return 1; 11089857Sobrien } 11189857Sobrien } 11289857Sobrien 11389857Sobrien if (DumpAsm) errs() << "Here's the assembly:\n" << *M.get(); 11489857Sobrien 11589857Sobrien if (!DisableOutput) 11689857Sobrien WriteOutputFile(M.get()); 11789857Sobrien 11889857Sobrien return 0; 11989857Sobrien} 12089857Sobrien