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