141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar//===-- cc1as_main.cpp - Clang Assembler  ---------------------------------===//
241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar//
341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar//                     The LLVM Compiler Infrastructure
441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar//
541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar// This file is distributed under the University of Illinois Open Source
641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar// License. See LICENSE.TXT for details.
741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar//
841b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar//===----------------------------------------------------------------------===//
941b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar//
1041b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar// This is the entry point to the clang -cc1as functionality, which implements
1141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar// the direct interface to the LLVM MC based assembler.
1241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar//
1341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar//===----------------------------------------------------------------------===//
1441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
1541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar#include "clang/Basic/Diagnostic.h"
16f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "clang/Basic/DiagnosticOptions.h"
17f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "clang/Driver/DriverDiagnostic.h"
1841b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar#include "clang/Driver/Options.h"
1941b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar#include "clang/Frontend/FrontendDiagnostic.h"
2041b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar#include "clang/Frontend/TextDiagnosticPrinter.h"
21b1e25a1bc03292dc538d336573e0be1490223171Reid Kleckner#include "clang/Frontend/Utils.h"
2241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar#include "llvm/ADT/StringSwitch.h"
232dc14532b641bae011a374e2c6c393d2196c1411Duncan Sands#include "llvm/ADT/Triple.h"
243b844ba7d5be205a9b4f5f0b0d1b7978977f4b8cChandler Carruth#include "llvm/IR/DataLayout.h"
25f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "llvm/MC/MCAsmBackend.h"
267374f1b407a86df83fde942ee9f3684a3159f99fDaniel Dunbar#include "llvm/MC/MCAsmInfo.h"
2741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar#include "llvm/MC/MCCodeEmitter.h"
2841b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar#include "llvm/MC/MCContext.h"
2974e1332a94e7c0214f8c2b7c7684a38ebd3f84a5Evan Cheng#include "llvm/MC/MCInstrInfo.h"
3036fc3aa1e30c69fc454d7cddd6e39f32a93db848Evan Cheng#include "llvm/MC/MCObjectFileInfo.h"
31f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "llvm/MC/MCParser/MCAsmParser.h"
32884744b65ec9d1669e145985bf1830e727c04952Evan Cheng#include "llvm/MC/MCRegisterInfo.h"
3341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar#include "llvm/MC/MCStreamer.h"
34bb36ed954a1ec9c6ec909b078c7828d75aa477afEvan Cheng#include "llvm/MC/MCSubtargetInfo.h"
353771235c9b8c34cee7c7f514f7dc406e2c05e267Evan Cheng#include "llvm/MC/MCTargetAsmParser.h"
366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/MC/MCTargetOptions.h"
37b1e25a1bc03292dc538d336573e0be1490223171Reid Kleckner#include "llvm/Option/Arg.h"
38b1e25a1bc03292dc538d336573e0be1490223171Reid Kleckner#include "llvm/Option/ArgList.h"
39b1e25a1bc03292dc538d336573e0be1490223171Reid Kleckner#include "llvm/Option/OptTable.h"
40c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar#include "llvm/Support/CommandLine.h"
4141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar#include "llvm/Support/ErrorHandling.h"
422669e96cc4f82db37fc0bea4fb95f56f5ff505a2Rafael Espindola#include "llvm/Support/FileSystem.h"
43f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "llvm/Support/FormattedStream.h"
44f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "llvm/Support/Host.h"
4541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar#include "llvm/Support/ManagedStatic.h"
4641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar#include "llvm/Support/MemoryBuffer.h"
4703013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Path.h"
48f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "llvm/Support/PrettyStackTrace.h"
4903013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Signals.h"
50f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "llvm/Support/SourceMgr.h"
51a6b4045dc462c03cd1e7cb9c3ec9dbfdb9c6ad62Evan Cheng#include "llvm/Support/TargetRegistry.h"
52a6b4045dc462c03cd1e7cb9c3ec9dbfdb9c6ad62Evan Cheng#include "llvm/Support/TargetSelect.h"
53a6b4045dc462c03cd1e7cb9c3ec9dbfdb9c6ad62Evan Cheng#include "llvm/Support/Timer.h"
54a6b4045dc462c03cd1e7cb9c3ec9dbfdb9c6ad62Evan Cheng#include "llvm/Support/raw_ostream.h"
55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <memory>
56ef8225444452a1486bd721f3285301fe84643b00Stephen Hines#include <system_error>
5741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbarusing namespace clang;
5841b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbarusing namespace clang::driver;
59ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesusing namespace clang::driver::options;
6041b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbarusing namespace llvm;
61b1e25a1bc03292dc538d336573e0be1490223171Reid Klecknerusing namespace llvm::opt;
6241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
6341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbarnamespace {
6441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
6541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar/// \brief Helper class for representing a single invocation of the assembler.
6641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbarstruct AssemblerInvocation {
6741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  /// @name Target Options
6841b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  /// @{
6941b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
70fc30829694e62040c14f329f5491724fe7476241Jim Grosbach  /// The name of the target triple to assemble for.
7141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  std::string Triple;
7241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
73fc30829694e62040c14f329f5491724fe7476241Jim Grosbach  /// If given, the name of the target CPU to determine which instructions
74fc30829694e62040c14f329f5491724fe7476241Jim Grosbach  /// are legal.
75fc30829694e62040c14f329f5491724fe7476241Jim Grosbach  std::string CPU;
76fc30829694e62040c14f329f5491724fe7476241Jim Grosbach
77fc30829694e62040c14f329f5491724fe7476241Jim Grosbach  /// The list of target specific features to enable or disable -- this should
78fc30829694e62040c14f329f5491724fe7476241Jim Grosbach  /// be a list of strings starting with '+' or '-'.
79fc30829694e62040c14f329f5491724fe7476241Jim Grosbach  std::vector<std::string> Features;
80fc30829694e62040c14f329f5491724fe7476241Jim Grosbach
8141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  /// @}
8241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  /// @name Language Options
8341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  /// @{
8441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
8541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  std::vector<std::string> IncludePaths;
8641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  unsigned NoInitialTextSection : 1;
87402adc3bc0ddbbb46cb0b8d29812a9c2f605ec4fDaniel Dunbar  unsigned SaveTemporaryLabels : 1;
88567003e572eed69cf1e8a04601076c8803355c7aKevin Enderby  unsigned GenDwarfForAssembly : 1;
89651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned CompressDebugSections : 1;
906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  unsigned DwarfVersion;
91567003e572eed69cf1e8a04601076c8803355c7aKevin Enderby  std::string DwarfDebugFlags;
920234179282d59e6dfccc8b2da72a9a71bf5b6ac3Kevin Enderby  std::string DwarfDebugProducer;
93d566df67bed6381f6e859bbd21fd43ff89277cc0Chandler Carruth  std::string DebugCompilationDir;
9427e2b983beb8b5a29869639637327725623069a8Eric Christopher  std::string MainFileName;
9541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
9641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  /// @}
9741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  /// @name Frontend Options
9841b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  /// @{
9941b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
10041b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  std::string InputFile;
101c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar  std::vector<std::string> LLVMArgs;
10241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  std::string OutputPath;
10341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  enum FileType {
10441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    FT_Asm,  ///< Assembly (.s) output, transliterate mode.
10541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    FT_Null, ///< No output, for timing purposes.
10641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    FT_Obj   ///< Object file output.
10741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  };
10841b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  FileType OutputType;
109c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar  unsigned ShowHelp : 1;
110c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar  unsigned ShowVersion : 1;
11141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
11241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  /// @}
11341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  /// @name Transliterate Options
11441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  /// @{
11541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
11641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  unsigned OutputAsmVariant;
11741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  unsigned ShowEncoding : 1;
11841b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  unsigned ShowInst : 1;
11941b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
12041b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  /// @}
12141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  /// @name Assembler Options
12241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  /// @{
12341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
12441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  unsigned RelaxAll : 1;
1253176cca2fe2bb9ab061e8e5fc05b4d59403fcf19Rafael Espindola  unsigned NoExecStack : 1;
12641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
12741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  /// @}
12841b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
12941b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbarpublic:
13041b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  AssemblerInvocation() {
13141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    Triple = "";
13241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    NoInitialTextSection = 0;
13341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    InputFile = "-";
134c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar    OutputPath = "-";
13541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    OutputType = FT_Asm;
13641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    OutputAsmVariant = 0;
13741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    ShowInst = 0;
13841b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    ShowEncoding = 0;
13941b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    RelaxAll = 0;
1403176cca2fe2bb9ab061e8e5fc05b4d59403fcf19Rafael Espindola    NoExecStack = 0;
1416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    DwarfVersion = 3;
14241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  }
14341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
1448fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith  static bool CreateFromArgs(AssemblerInvocation &Res, const char **ArgBegin,
145d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie                             const char **ArgEnd, DiagnosticsEngine &Diags);
14641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar};
14741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
14841b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar}
14941b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
1508fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmithbool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
15141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar                                         const char **ArgBegin,
15241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar                                         const char **ArgEnd,
153d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie                                         DiagnosticsEngine &Diags) {
1548fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith  bool Success = true;
1558fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith
15641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // Parse the arguments.
157ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  std::unique_ptr<OptTable> OptTbl(createDriverOptTable());
158ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
159ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  const unsigned IncludedFlagsBitmask = options::CC1AsOption;
16041b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  unsigned MissingArgIndex, MissingArgCount;
161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<InputArgList> Args(
162ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      OptTbl->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount,
163ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                        IncludedFlagsBitmask));
16441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
16541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // Check for missing argument error.
1668fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith  if (MissingArgCount) {
16741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    Diags.Report(diag::err_drv_missing_argument)
168ef8225444452a1486bd721f3285301fe84643b00Stephen Hines        << Args->getArgString(MissingArgIndex) << MissingArgCount;
1698fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith    Success = false;
1708fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith  }
17141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
17241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // Issue errors on unknown arguments.
173ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  for (arg_iterator it = Args->filtered_begin(OPT_UNKNOWN),
174ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                    ie = Args->filtered_end();
175ef8225444452a1486bd721f3285301fe84643b00Stephen Hines       it != ie; ++it) {
176ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Diags.Report(diag::err_drv_unknown_argument) << (*it)->getAsString(*Args);
1778fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith    Success = false;
1788fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith  }
17941b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
18041b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // Construct the invocation.
18141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
18241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // Target Options
183fc30829694e62040c14f329f5491724fe7476241Jim Grosbach  Opts.Triple = llvm::Triple::normalize(Args->getLastArgValue(OPT_triple));
184fc30829694e62040c14f329f5491724fe7476241Jim Grosbach  Opts.CPU = Args->getLastArgValue(OPT_target_cpu);
185fc30829694e62040c14f329f5491724fe7476241Jim Grosbach  Opts.Features = Args->getAllArgValues(OPT_target_feature);
186fc30829694e62040c14f329f5491724fe7476241Jim Grosbach
187fc30829694e62040c14f329f5491724fe7476241Jim Grosbach  // Use the default target triple if unspecified.
188fc30829694e62040c14f329f5491724fe7476241Jim Grosbach  if (Opts.Triple.empty())
189fc30829694e62040c14f329f5491724fe7476241Jim Grosbach    Opts.Triple = llvm::sys::getDefaultTargetTriple();
19041b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
19141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // Language Options
19241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  Opts.IncludePaths = Args->getAllArgValues(OPT_I);
19341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  Opts.NoInitialTextSection = Args->hasArg(OPT_n);
194084be2df33f5ac99ba989b519921014d236aea10Bob Wilson  Opts.SaveTemporaryLabels = Args->hasArg(OPT_msave_temp_labels);
195ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  Opts.GenDwarfForAssembly = Args->hasArg(OPT_g_Flag);
196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Opts.CompressDebugSections = Args->hasArg(OPT_compress_debug_sections);
1976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (Args->hasArg(OPT_gdwarf_2))
1986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    Opts.DwarfVersion = 2;
1996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (Args->hasArg(OPT_gdwarf_3))
2006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    Opts.DwarfVersion = 3;
2016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (Args->hasArg(OPT_gdwarf_4))
2026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    Opts.DwarfVersion = 4;
203567003e572eed69cf1e8a04601076c8803355c7aKevin Enderby  Opts.DwarfDebugFlags = Args->getLastArgValue(OPT_dwarf_debug_flags);
2040234179282d59e6dfccc8b2da72a9a71bf5b6ac3Kevin Enderby  Opts.DwarfDebugProducer = Args->getLastArgValue(OPT_dwarf_debug_producer);
205d566df67bed6381f6e859bbd21fd43ff89277cc0Chandler Carruth  Opts.DebugCompilationDir = Args->getLastArgValue(OPT_fdebug_compilation_dir);
20627e2b983beb8b5a29869639637327725623069a8Eric Christopher  Opts.MainFileName = Args->getLastArgValue(OPT_main_file_name);
20741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
20841b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // Frontend Options
20941b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  if (Args->hasArg(OPT_INPUT)) {
21041b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    bool First = true;
21141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    for (arg_iterator it = Args->filtered_begin(OPT_INPUT),
21241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar           ie = Args->filtered_end(); it != ie; ++it, First=false) {
2137e4953e5c60409007545288f14b430bd23d68570Daniel Dunbar      const Arg *A = it;
21441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar      if (First)
2151d489cf4a04ad0ad8ac2696e4eed0995f3a67288Richard Smith        Opts.InputFile = A->getValue();
2168fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith      else {
2177e4953e5c60409007545288f14b430bd23d68570Daniel Dunbar        Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(*Args);
2188fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith        Success = false;
2198fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith      }
22041b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    }
22141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  }
222c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar  Opts.LLVMArgs = Args->getAllArgValues(OPT_mllvm);
22341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  Opts.OutputPath = Args->getLastArgValue(OPT_o);
22441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  if (Arg *A = Args->getLastArg(OPT_filetype)) {
2251d489cf4a04ad0ad8ac2696e4eed0995f3a67288Richard Smith    StringRef Name = A->getValue();
22641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    unsigned OutputType = StringSwitch<unsigned>(Name)
22741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar      .Case("asm", FT_Asm)
22841b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar      .Case("null", FT_Null)
22941b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar      .Case("obj", FT_Obj)
23041b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar      .Default(~0U);
2318fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith    if (OutputType == ~0U) {
23241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar      Diags.Report(diag::err_drv_invalid_value)
23341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar        << A->getAsString(*Args) << Name;
2348fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith      Success = false;
2358fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith    } else
23641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar      Opts.OutputType = FileType(OutputType);
23741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  }
238c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar  Opts.ShowHelp = Args->hasArg(OPT_help);
239c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar  Opts.ShowVersion = Args->hasArg(OPT_version);
24041b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
24141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // Transliterate Options
242b1e25a1bc03292dc538d336573e0be1490223171Reid Kleckner  Opts.OutputAsmVariant =
243b1e25a1bc03292dc538d336573e0be1490223171Reid Kleckner      getLastArgIntValue(*Args.get(), OPT_output_asm_variant, 0, Diags);
24441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  Opts.ShowEncoding = Args->hasArg(OPT_show_encoding);
24541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  Opts.ShowInst = Args->hasArg(OPT_show_inst);
24641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
24741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // Assemble Options
24873168db4feadbb5e8915e71369aad33292860427David Blaikie  Opts.RelaxAll = Args->hasArg(OPT_mrelax_all);
24973168db4feadbb5e8915e71369aad33292860427David Blaikie  Opts.NoExecStack =  Args->hasArg(OPT_mno_exec_stack);
2508fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith
25189ea416d3f75a78a8bf5398e316e2a6281ed57b7Dylan Noblesmith  return Success;
25241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar}
25341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
25441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbarstatic formatted_raw_ostream *GetOutputStream(AssemblerInvocation &Opts,
255d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie                                              DiagnosticsEngine &Diags,
25641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar                                              bool Binary) {
257c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar  if (Opts.OutputPath.empty())
258c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar    Opts.OutputPath = "-";
259c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar
26041b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // Make sure that the Out file gets unlinked from the disk if we get a
26141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // SIGINT.
26241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  if (Opts.OutputPath != "-")
2636f2e23b25d9be365266be43ffa1cf6f850b6027eRafael Espindola    sys::RemoveFileOnSignal(Opts.OutputPath);
26441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
26541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  std::string Error;
26641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  raw_fd_ostream *Out =
267d965f95daa97097c8ddc5e1165ceae585a888719Rafael Espindola      new raw_fd_ostream(Opts.OutputPath.c_str(), Error,
268651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                         (Binary ? sys::fs::F_None : sys::fs::F_Text));
26941b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  if (!Error.empty()) {
27041b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    Diags.Report(diag::err_fe_unable_to_open_output)
27141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar      << Opts.OutputPath << Error;
272ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    delete Out;
273ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return nullptr;
27441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  }
27541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
27641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  return new formatted_raw_ostream(*Out, formatted_raw_ostream::DELETE_STREAM);
27741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar}
27841b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
279d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikiestatic bool ExecuteAssembler(AssemblerInvocation &Opts,
280d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie                             DiagnosticsEngine &Diags) {
28141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // Get the target specific parser.
28241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  std::string Error;
283ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  const Target *TheTarget = TargetRegistry::lookupTarget(Opts.Triple, Error);
284ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (!TheTarget)
285ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
28641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
287ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
288ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      MemoryBuffer::getFileOrSTDIN(Opts.InputFile);
289ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
290ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (std::error_code EC = Buffer.getError()) {
291ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Error = EC.message();
292ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return Diags.Report(diag::err_fe_error_reading) << Opts.InputFile;
29341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  }
29441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
29541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  SourceMgr SrcMgr;
29641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
29741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // Tell SrcMgr about this buffer, which is what the parser will pick up.
298ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  SrcMgr.AddNewSourceBuffer(Buffer->release(), SMLoc());
29941b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
30041b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // Record the location of the include directories so that the lexer can find
30141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // it later.
30241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  SrcMgr.setIncludeDirs(Opts.IncludePaths);
30341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
304651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple));
305884744b65ec9d1669e145985bf1830e727c04952Evan Cheng  assert(MRI && "Unable to create target register info!");
306884744b65ec9d1669e145985bf1830e727c04952Evan Cheng
307651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, Opts.Triple));
3081fcf31efaf58fcdf274409cf8926915636bce033Rafael Espindola  assert(MAI && "Unable to create target asm info!");
3091fcf31efaf58fcdf274409cf8926915636bce033Rafael Espindola
310651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Ensure MCAsmInfo initialization occurs before any use, otherwise sections
311651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // may be created with a combination of default and explicit settings.
312651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (Opts.CompressDebugSections)
313651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    MAI->setCompressDebugSections(true);
314651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
31541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj;
316ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  std::unique_ptr<formatted_raw_ostream> Out(
317ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      GetOutputStream(Opts, Diags, IsBinary));
31841b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  if (!Out)
319ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return true;
32041b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
32136fc3aa1e30c69fc454d7cddd6e39f32a93db848Evan Cheng  // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
32236fc3aa1e30c69fc454d7cddd6e39f32a93db848Evan Cheng  // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
323651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
324651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3254b7bae35fc29190f30ddabf314864ac7a7bd1c04Bill Wendling  MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr);
32636fc3aa1e30c69fc454d7cddd6e39f32a93db848Evan Cheng  // FIXME: Assembler behavior can change with -static.
32766488ed140f00daee0c3f0370bac337819ee8bc0Evan Cheng  MOFI->InitMCObjectFileInfo(Opts.Triple,
32866488ed140f00daee0c3f0370bac337819ee8bc0Evan Cheng                             Reloc::Default, CodeModel::Default, Ctx);
329402adc3bc0ddbbb46cb0b8d29812a9c2f605ec4fDaniel Dunbar  if (Opts.SaveTemporaryLabels)
330402adc3bc0ddbbb46cb0b8d29812a9c2f605ec4fDaniel Dunbar    Ctx.setAllowTemporaryLabels(false);
331567003e572eed69cf1e8a04601076c8803355c7aKevin Enderby  if (Opts.GenDwarfForAssembly)
332567003e572eed69cf1e8a04601076c8803355c7aKevin Enderby    Ctx.setGenDwarfForAssembly(true);
333567003e572eed69cf1e8a04601076c8803355c7aKevin Enderby  if (!Opts.DwarfDebugFlags.empty())
334567003e572eed69cf1e8a04601076c8803355c7aKevin Enderby    Ctx.setDwarfDebugFlags(StringRef(Opts.DwarfDebugFlags));
3350234179282d59e6dfccc8b2da72a9a71bf5b6ac3Kevin Enderby  if (!Opts.DwarfDebugProducer.empty())
3360234179282d59e6dfccc8b2da72a9a71bf5b6ac3Kevin Enderby    Ctx.setDwarfDebugProducer(StringRef(Opts.DwarfDebugProducer));
337d566df67bed6381f6e859bbd21fd43ff89277cc0Chandler Carruth  if (!Opts.DebugCompilationDir.empty())
338d566df67bed6381f6e859bbd21fd43ff89277cc0Chandler Carruth    Ctx.setCompilationDir(Opts.DebugCompilationDir);
33927e2b983beb8b5a29869639637327725623069a8Eric Christopher  if (!Opts.MainFileName.empty())
34027e2b983beb8b5a29869639637327725623069a8Eric Christopher    Ctx.setMainFileName(StringRef(Opts.MainFileName));
3416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Ctx.setDwarfVersion(Opts.DwarfVersion);
3427872d48c615c274e6055ed06d9c4b9ace4f8778dRafael Espindola
343fc30829694e62040c14f329f5491724fe7476241Jim Grosbach  // Build up the feature string from the target feature list.
344fc30829694e62040c14f329f5491724fe7476241Jim Grosbach  std::string FS;
345fc30829694e62040c14f329f5491724fe7476241Jim Grosbach  if (!Opts.Features.empty()) {
346fc30829694e62040c14f329f5491724fe7476241Jim Grosbach    FS = Opts.Features[0];
347fc30829694e62040c14f329f5491724fe7476241Jim Grosbach    for (unsigned i = 1, e = Opts.Features.size(); i != e; ++i)
348fc30829694e62040c14f329f5491724fe7476241Jim Grosbach      FS += "," + Opts.Features[i];
349fc30829694e62040c14f329f5491724fe7476241Jim Grosbach  }
350fc30829694e62040c14f329f5491724fe7476241Jim Grosbach
351651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<MCStreamer> Str;
35241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
353651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
354651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<MCSubtargetInfo> STI(
355651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));
35674e1332a94e7c0214f8c2b7c7684a38ebd3f84a5Evan Cheng
3573176cca2fe2bb9ab061e8e5fc05b4d59403fcf19Rafael Espindola  // FIXME: There is a bit of code duplication with addPassesToEmitFile.
35841b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
35941b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    MCInstPrinter *IP =
36099d43b4085c7dc85e6bf2612df2061988bc979adBill Wendling      TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI, *MCII, *MRI,
36199d43b4085c7dc85e6bf2612df2061988bc979adBill Wendling                                     *STI);
362ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    MCCodeEmitter *CE = nullptr;
363ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    MCAsmBackend *MAB = nullptr;
36466cdf26f28c8f22de9def1d62f7d65447c86b7f1Daniel Dunbar    if (Opts.ShowEncoding) {
36592ecfe9c475c1ef2ae9b3523234a88b44fd0b9bbJim Grosbach      CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
366e904acfb439faa186fcbe7312861a222d8df4f91Bill Wendling      MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple, Opts.CPU);
36766cdf26f28c8f22de9def1d62f7d65447c86b7f1Daniel Dunbar    }
3687872d48c615c274e6055ed06d9c4b9ace4f8778dRafael Espindola    Str.reset(TheTarget->createAsmStreamer(Ctx, *Out, /*asmverbose*/true,
369ea523d73a6de06f828952a02f5ff86e4cc631695Nick Lewycky                                           /*useDwarfDirectory*/ true,
370ea523d73a6de06f828952a02f5ff86e4cc631695Nick Lewycky                                           IP, CE, MAB,
3717872d48c615c274e6055ed06d9c4b9ace4f8778dRafael Espindola                                           Opts.ShowInst));
37241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  } else if (Opts.OutputType == AssemblerInvocation::FT_Null) {
37341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    Str.reset(createNullStreamer(Ctx));
37441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  } else {
37541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar    assert(Opts.OutputType == AssemblerInvocation::FT_Obj &&
37641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar           "Invalid file type!");
37792ecfe9c475c1ef2ae9b3523234a88b44fd0b9bbJim Grosbach    MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
378e904acfb439faa186fcbe7312861a222d8df4f91Bill Wendling    MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple,
379e904acfb439faa186fcbe7312861a222d8df4f91Bill Wendling                                                      Opts.CPU);
3807b6def7d172e457826ddc2839fc6d4cb6d9abb7fEvan Cheng    Str.reset(TheTarget->createMCObjectStreamer(Opts.Triple, Ctx, *MAB, *Out,
381651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                                CE, *STI, Opts.RelaxAll,
3827b6def7d172e457826ddc2839fc6d4cb6d9abb7fEvan Cheng                                                Opts.NoExecStack));
3834f036fad0481a1bc996763b3e7c1d2f0019607f4Rafael Espindola    Str.get()->InitSections();
38441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  }
38541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
386ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  bool Failed = false;
387ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
388651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<MCAsmParser> Parser(
389651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));
3906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
3916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // FIXME: init MCTargetOptions from sanitizer flags here.
3926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  MCTargetOptions Options;
393651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<MCTargetAsmParser> TAP(
3946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      TheTarget->createMCAsmParser(*STI, *Parser, *MCII, Options));
395ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (!TAP)
396ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Failed = Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
39741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
398ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (!Failed) {
399ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Parser->setTargetParser(*TAP.get());
400ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Failed = Parser->Run(Opts.NoInitialTextSection);
401ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  }
40241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
403ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  // Close the output stream early.
404ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  Out.reset();
40541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
406ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  // Delete output file if there were errors.
407ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (Failed && Opts.OutputPath != "-")
4082669e96cc4f82db37fc0bea4fb95f56f5ff505a2Rafael Espindola    sys::fs::remove(Opts.OutputPath);
40941b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
410ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return Failed;
41141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar}
41241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
4139083628fec737679eb95abe8e2e5e23717a96e18Chad Rosierstatic void LLVMErrorHandler(void *UserData, const std::string &Message,
4149083628fec737679eb95abe8e2e5e23717a96e18Chad Rosier                             bool GenCrashDiag) {
415d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  DiagnosticsEngine &Diags = *static_cast<DiagnosticsEngine*>(UserData);
41641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
41741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  Diags.Report(diag::err_fe_error_backend) << Message;
41841b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
41941b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // We cannot recover from llvm errors.
42041b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  exit(1);
42141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar}
42241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
42341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbarint cc1as_main(const char **ArgBegin, const char **ArgEnd,
42441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar               const char *Argv0, void *MainAddr) {
42541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // Print a stack trace if we signal out.
42641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  sys::PrintStackTraceOnErrorSignal();
42741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  PrettyStackTraceProgram X(ArgEnd - ArgBegin, ArgBegin);
42841b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
42941b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
43041b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // Initialize targets and assembly printers/parsers.
43141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  InitializeAllTargetInfos();
432d99d3e1c01874d3f07b9670ae1cfdc4bef895049Evan Cheng  InitializeAllTargetMCs();
43341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  InitializeAllAsmParsers();
43441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
43541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // Construct our diagnostic client.
43602c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
437bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor  TextDiagnosticPrinter *DiagClient
43802c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor    = new TextDiagnosticPrinter(errs(), &*DiagOpts);
439bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor  DiagClient->setPrefix("clang -cc1as");
440c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith  IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
44102c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
44241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
44341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // Set an error handler, so that any LLVM backend diagnostics go through our
44441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // error handler.
445726578c22e9e33774435257664f8f6dc4cf8dfa9Dan Gohman  ScopedFatalErrorHandler FatalErrorHandler
446726578c22e9e33774435257664f8f6dc4cf8dfa9Dan Gohman    (LLVMErrorHandler, static_cast<void*>(&Diags));
44741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
44841b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // Parse the arguments.
44941b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  AssemblerInvocation Asm;
4508fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith  if (!AssemblerInvocation::CreateFromArgs(Asm, ArgBegin, ArgEnd, Diags))
4518fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith    return 1;
45241b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
453c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar  if (Asm.ShowHelp) {
454ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    std::unique_ptr<OptTable> Opts(driver::createDriverOptTable());
455ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Opts->PrintHelp(llvm::outs(), "clang -cc1as", "Clang Integrated Assembler",
456ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                    /*Include=*/driver::options::CC1AsOption, /*Exclude=*/0);
457c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar    return 0;
458c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar  }
459c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar
460c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar  // Honor -version.
461c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar  //
462c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar  // FIXME: Use a better -version message?
463c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar  if (Asm.ShowVersion) {
464c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar    llvm::cl::PrintVersionMessage();
465c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar    return 0;
466c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar  }
467c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar
468c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar  // Honor -mllvm.
469c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar  //
470c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar  // FIXME: Remove this, one day.
471c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar  if (!Asm.LLVMArgs.empty()) {
472c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar    unsigned NumArgs = Asm.LLVMArgs.size();
473c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar    const char **Args = new const char*[NumArgs + 2];
474c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar    Args[0] = "clang (LLVM option parsing)";
475c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar    for (unsigned i = 0; i != NumArgs; ++i)
476c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar      Args[i + 1] = Asm.LLVMArgs[i].c_str();
477ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Args[NumArgs + 1] = nullptr;
4786bd17d2f2e6e498b0ff01e2e755f044de046d138David Blaikie    llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args);
479c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar  }
480c673af7fe67e5db4d10dd414237df247d35dd9d9Daniel Dunbar
48141b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // Execute the invocation, unless there were parsing errors.
482ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  bool Failed = Diags.hasErrorOccurred() || ExecuteAssembler(Asm, Diags);
48341b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
48441b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // If any timers were active but haven't been destroyed yet, print their
48541b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  // results now.
48641b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar  TimerGroup::printAll(errs());
48741b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar
488ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return !!Failed;
48941b5b17445ab3bdf957ebd4be6c8670f09a212a8Daniel Dunbar}
490ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
491