work around an MSVC2010 bug, PR6504
[oota-llvm.git] / tools / llvm-mc / llvm-mc.cpp
index 342ae99b5376a42808a56e480d1db5d3ea291409..66e126092db226c01bd347404159d3a09239f224 100644 (file)
@@ -26,7 +26,9 @@
 #include "llvm/Support/PrettyStackTrace.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Host.h"
 #include "llvm/System/Signals.h"
+#include "llvm/Target/TargetAsmBackend.h"
 #include "llvm/Target/TargetAsmParser.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetRegistry.h"
@@ -46,6 +48,9 @@ OutputFilename("o", cl::desc("Output filename"),
 static cl::opt<bool>
 ShowEncoding("show-encoding", cl::desc("Show instruction encodings"));
 
+static cl::opt<bool>
+ShowInst("show-inst", cl::desc("Show internal instruction representation"));
+
 static cl::opt<unsigned>
 OutputAsmVariant("output-asm-variant",
                  cl::desc("Syntax variant to use for output printing"));
@@ -71,10 +76,17 @@ static cl::list<std::string>
 IncludeDirs("I", cl::desc("Directory of include files"),
             cl::value_desc("directory"), cl::Prefix);
 
+static cl::opt<std::string>
+ArchName("arch", cl::desc("Target arch to assemble for, "
+                            "see -version for available targets"));
+
 static cl::opt<std::string>
 TripleName("triple", cl::desc("Target triple to assemble for, "
-                              "see -version for available targets"),
-           cl::init(LLVM_HOSTTRIPLE));
+                              "see -version for available targets"));
+
+static cl::opt<bool>
+NoInitialTextSection("n", cl::desc(
+                   "Don't assume assembly file starts in the text section"));
 
 enum ActionType {
   AC_AsLex,
@@ -94,6 +106,15 @@ Action(cl::desc("Action to perform:"),
                   clEnumValEnd));
 
 static const Target *GetTarget(const char *ProgName) {
+  // Figure out the target triple.
+  if (TripleName.empty())
+    TripleName = sys::getHostTriple();
+  if (!ArchName.empty()) {
+    llvm::Triple TT(TripleName);
+    TT.setArchName(ArchName);
+    TripleName = TT.str();
+  }
+
   // Get the target specific parser.
   std::string Error;
   const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
@@ -238,7 +259,11 @@ static int AssembleInput(const char *ProgName) {
   // it later.
   SrcMgr.setIncludeDirs(IncludeDirs);
   
-  MCContext Ctx;
+  
+  const MCAsmInfo *MAI = TheTarget->createAsmInfo(TripleName);
+  assert(MAI && "Unable to create target asm info!");
+  
+  MCContext Ctx(*MAI);
   formatted_raw_ostream *Out = GetOutputStream();
   if (!Out)
     return 1;
@@ -256,21 +281,20 @@ static int AssembleInput(const char *ProgName) {
   OwningPtr<MCInstPrinter> IP;
   OwningPtr<MCCodeEmitter> CE;
   OwningPtr<MCStreamer> Str;
-
-  const MCAsmInfo *MAI = TheTarget->createAsmInfo(TripleName);
-  assert(MAI && "Unable to create target asm info!");
+  OwningPtr<TargetAsmBackend> TAB;
 
   if (FileType == OFT_AssemblyFile) {
     IP.reset(TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *Out));
     if (ShowEncoding)
-      CE.reset(TheTarget->createCodeEmitter(*TM));
-    Str.reset(createAsmStreamer(Ctx, *Out, *MAI,
-                                TM->getTargetData()->isLittleEndian(),
-                                /*asmverbose*/true, IP.get(), CE.get()));
+      CE.reset(TheTarget->createCodeEmitter(*TM, Ctx));
+    Str.reset(createAsmStreamer(Ctx, *Out,TM->getTargetData()->isLittleEndian(),
+                                /*asmverbose*/true, IP.get(), CE.get(),
+                                ShowInst));
   } else {
     assert(FileType == OFT_ObjectFile && "Invalid file type!");
-    CE.reset(TheTarget->createCodeEmitter(*TM));
-    Str.reset(createMachOStreamer(Ctx, *Out, CE.get()));
+    CE.reset(TheTarget->createCodeEmitter(*TM, Ctx));
+    TAB.reset(TheTarget->createAsmBackend(TripleName));
+    Str.reset(createMachOStreamer(Ctx, *TAB, *Out, CE.get()));
   }
 
   AsmParser Parser(SrcMgr, Ctx, *Str.get(), *MAI);
@@ -283,10 +307,14 @@ static int AssembleInput(const char *ProgName) {
 
   Parser.setTargetParser(*TAP.get());
 
-  int Res = Parser.Run();
+  int Res = Parser.Run(NoInitialTextSection);
   if (Out != &fouts())
     delete Out;
 
+  // Delete output on errors.
+  if (Res && OutputFilename != "-")
+    sys::Path(OutputFilename).eraseFromDisk();
+
   return Res;
 }