1193323Sed//===--- llvm-as.cpp - The low-level LLVM assembler -----------------------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed//  This utility may be invoked in the following manner:
11193323Sed//   llvm-as --help         - Output information about command line switches
12193323Sed//   llvm-as [options]      - Read LLVM asm from stdin, write bitcode to stdout
13193323Sed//   llvm-as [options] x.ll - Read LLVM asm from the x.ll file, write bitcode
14193323Sed//                            to the x.bc file.
15193323Sed//
16193323Sed//===----------------------------------------------------------------------===//
17193323Sed
18249423Sdim#include "llvm/IR/LLVMContext.h"
19249423Sdim#include "llvm/Analysis/Verifier.h"
20193323Sed#include "llvm/Assembly/Parser.h"
21193323Sed#include "llvm/Bitcode/ReaderWriter.h"
22249423Sdim#include "llvm/IR/Module.h"
23193323Sed#include "llvm/Support/CommandLine.h"
24193323Sed#include "llvm/Support/ManagedStatic.h"
25193323Sed#include "llvm/Support/PrettyStackTrace.h"
26249423Sdim#include "llvm/Support/Signals.h"
27195340Sed#include "llvm/Support/SourceMgr.h"
28193323Sed#include "llvm/Support/SystemUtils.h"
29218885Sdim#include "llvm/Support/ToolOutputFile.h"
30193323Sed#include <memory>
31193323Sedusing namespace llvm;
32193323Sed
33193323Sedstatic cl::opt<std::string>
34193323SedInputFilename(cl::Positional, cl::desc("<input .llvm file>"), cl::init("-"));
35193323Sed
36193323Sedstatic cl::opt<std::string>
37193323SedOutputFilename("o", cl::desc("Override output filename"),
38193323Sed               cl::value_desc("filename"));
39193323Sed
40193323Sedstatic cl::opt<bool>
41198090SrdivackyForce("f", cl::desc("Enable binary output on terminals"));
42193323Sed
43193323Sedstatic cl::opt<bool>
44193323SedDisableOutput("disable-output", cl::desc("Disable output"), cl::init(false));
45193323Sed
46193323Sedstatic cl::opt<bool>
47193323SedDumpAsm("d", cl::desc("Print assembly as parsed"), cl::Hidden);
48193323Sed
49193323Sedstatic cl::opt<bool>
50193323SedDisableVerify("disable-verify", cl::Hidden,
51193323Sed              cl::desc("Do not run verifier on input LLVM (dangerous!)"));
52193323Sed
53198396Srdivackystatic void WriteOutputFile(const Module *M) {
54198090Srdivacky  // Infer the output filename if needed.
55198090Srdivacky  if (OutputFilename.empty()) {
56198090Srdivacky    if (InputFilename == "-") {
57198090Srdivacky      OutputFilename = "-";
58193323Sed    } else {
59198090Srdivacky      std::string IFN = InputFilename;
60198090Srdivacky      int Len = IFN.length();
61198090Srdivacky      if (IFN[Len-3] == '.' && IFN[Len-2] == 'l' && IFN[Len-1] == 'l') {
62198090Srdivacky        // Source ends in .ll
63198090Srdivacky        OutputFilename = std::string(IFN.begin(), IFN.end()-3);
64193323Sed      } else {
65198090Srdivacky        OutputFilename = IFN;   // Append a .bc to it
66193323Sed      }
67198090Srdivacky      OutputFilename += ".bc";
68193323Sed    }
69198090Srdivacky  }
70193323Sed
71198090Srdivacky  std::string ErrorInfo;
72263508Sdim  OwningPtr<tool_output_file> Out(new tool_output_file(
73263508Sdim      OutputFilename.c_str(), ErrorInfo, sys::fs::F_Binary));
74198090Srdivacky  if (!ErrorInfo.empty()) {
75198090Srdivacky    errs() << ErrorInfo << '\n';
76198396Srdivacky    exit(1);
77198396Srdivacky  }
78198396Srdivacky
79212793Sdim  if (Force || !CheckBitcodeOutputToConsole(Out->os(), true))
80212793Sdim    WriteBitcodeToFile(M, Out->os());
81212793Sdim
82212793Sdim  // Declare success.
83212793Sdim  Out->keep();
84198396Srdivacky}
85198396Srdivacky
86198396Srdivackyint main(int argc, char **argv) {
87198396Srdivacky  // Print a stack trace if we signal out.
88198396Srdivacky  sys::PrintStackTraceOnErrorSignal();
89198396Srdivacky  PrettyStackTraceProgram X(argc, argv);
90198396Srdivacky  LLVMContext &Context = getGlobalContext();
91198396Srdivacky  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
92198396Srdivacky  cl::ParseCommandLineOptions(argc, argv, "llvm .ll -> .bc assembler\n");
93198396Srdivacky
94198396Srdivacky  // Parse the file now...
95198396Srdivacky  SMDiagnostic Err;
96251662Sdim  OwningPtr<Module> M(ParseAssemblyFile(InputFilename, Err, Context));
97198396Srdivacky  if (M.get() == 0) {
98234353Sdim    Err.print(argv[0], errs());
99198090Srdivacky    return 1;
100193323Sed  }
101193323Sed
102198396Srdivacky  if (!DisableVerify) {
103198396Srdivacky    std::string Err;
104198396Srdivacky    if (verifyModule(*M.get(), ReturnStatusAction, &Err)) {
105198396Srdivacky      errs() << argv[0]
106198396Srdivacky             << ": assembly parsed, but does not verify as correct!\n";
107198396Srdivacky      errs() << Err;
108198396Srdivacky      return 1;
109198396Srdivacky    }
110198396Srdivacky  }
111198396Srdivacky
112198396Srdivacky  if (DumpAsm) errs() << "Here's the assembly:\n" << *M.get();
113198396Srdivacky
114198090Srdivacky  if (!DisableOutput)
115198396Srdivacky    WriteOutputFile(M.get());
116198396Srdivacky
117198090Srdivacky  return 0;
118193323Sed}
119