Finegrainify namespacification
[oota-llvm.git] / utils / TableGen / TableGen.cpp
index 8a22c54e472a124ba959a0bf5ba6b54fb44db068..7bd52b37cf06eaf602f9266d0d10d18ab87d39fb 100644 (file)
@@ -1,4 +1,11 @@
 //===- TableGen.cpp - Top-Level TableGen implementation -------------------===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
 //
 // TableGen is a tool which can be used to build up a description of something,
 // then invoke one or more "tablegen backends" to emit information about the
 
 #include "Record.h"
 #include "Support/CommandLine.h"
-#include "Support/Signals.h"
+#include "llvm/System/Signals.h"
 #include "Support/FileUtilities.h"
 #include "CodeEmitterGen.h"
 #include "RegisterInfoEmitter.h"
 #include "InstrInfoEmitter.h"
+#include "InstrSelectorEmitter.h"
 #include <algorithm>
+#include <cstdio>
 #include <fstream>
+using namespace llvm;
 
 enum ActionType {
   PrintRecords,
   GenEmitter,
   GenRegisterEnums, GenRegister, GenRegisterHeader,
-  GenInstrEnums, GenInstrs,
+  GenInstrEnums, GenInstrs, GenInstrSelector,
   PrintEnums,
-  Parse,
+  Parse
 };
 
 namespace {
@@ -44,11 +54,13 @@ namespace {
                                "Generate enum values for instructions"),
                     clEnumValN(GenInstrs, "gen-instr-desc",
                                "Generate instruction descriptions"),
+                    clEnumValN(GenInstrSelector, "gen-instr-selector",
+                               "Generate an instruction selector"),
                     clEnumValN(PrintEnums, "print-enums",
                                "Print enum values for a class"),
                     clEnumValN(Parse, "parse",
                                "Interpret machine code (testing only)"),
-                    0));
+                    clEnumValEnd));
 
   cl::opt<std::string>
   Class("class", cl::desc("Print Enum list for this class"),
@@ -60,12 +72,18 @@ namespace {
 
   cl::opt<std::string>
   InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
-}
 
+  cl::opt<std::string>
+  IncludeDir("I", cl::desc("Directory of include files"),
+                  cl::value_desc("directory"), cl::init(""));
+}
 
-void ParseFile(const std::string &Filename);
+namespace llvm {
+  void ParseFile(const std::string &Filename,
+                 const std::string &IncludeDir);
+}
 
-RecordKeeper Records;
+RecordKeeper llvm::Records;
 
 static Init *getBit(Record *R, unsigned BitNo) {
   const std::vector<RecordVal> &V = R->getValues();
@@ -80,7 +98,7 @@ static Init *getBit(Record *R, unsigned BitNo) {
     }
 
   std::cerr << "Cannot find requested bit!\n";
-  abort();
+  exit(1);
   return 0;
 }
 
@@ -185,9 +203,9 @@ static unsigned getFirstFixedBitInSequence(std::vector<Record*>::iterator IB,
 }
 
 // ParseMachineCode - Try to split the vector of instructions (which is
-// intentially taken by-copy) in half, narrowing down the possible instructions
-// that we may have found.  Eventually, this list will get pared down to zero or
-// one instruction, in which case we have a match or failure.
+// intentionally taken by-copy) in half, narrowing down the possible
+// instructions that we may have found.  Eventually, this list will get pared
+// down to zero or one instruction, in which case we have a match or failure.
 //
 static Record *ParseMachineCode(std::vector<Record*>::iterator InstsB, 
                                std::vector<Record*>::iterator InstsE,
@@ -256,7 +274,7 @@ static Record *ParseMachineCode(std::vector<Record*>::iterator InstsB,
     if (RangeBegin == InstsB && RangeEnd == InstsE) {
       std::cerr << "Error: Could not distinguish among the following insts!:\n";
       PrintRange(InstsB, InstsE);
-      abort();
+      exit(1);
     }
     
 #if 0
@@ -391,25 +409,21 @@ static void ParseMachineCode() {
   }
 }
 
-
 int main(int argc, char **argv) {
   cl::ParseCommandLineOptions(argc, argv);
-  ParseFile(InputFilename);
+  ParseFile(InputFilename, IncludeDir);
 
   std::ostream *Out = &std::cout;
   if (OutputFilename != "-") {
-    // Output to a .tmp file, because we don't actually want to overwrite the
-    // output file unless the generated file is different or the specified file
-    // does not exist.
-    Out = new std::ofstream((OutputFilename+".tmp").c_str());
+    Out = new std::ofstream(OutputFilename.c_str());
 
     if (!Out->good()) {
-      std::cerr << argv[0] << ": error opening " << OutputFilename << ".tmp!\n";
+      std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
       return 1;
     }
 
     // Make sure the file gets removed if *gasp* tablegen crashes...
-    RemoveFileOnSignal(OutputFilename+".tmp");
+    RemoveFileOnSignal(OutputFilename);
   }
 
   try {
@@ -440,14 +454,21 @@ int main(int argc, char **argv) {
     case GenInstrs:
       InstrInfoEmitter(Records).run(*Out);
       break;
-
+    case GenInstrSelector:
+      InstrSelectorEmitter(Records).run(*Out);
+      break;
     case PrintEnums:
+    {
       std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);
       for (unsigned i = 0, e = Recs.size(); i != e; ++i)
-        *Out << Recs[i] << ", ";
+        *Out << Recs[i]->getName() << ", ";
       *Out << "\n";
       break;
     }
+    default:
+      assert(1 && "Invalid Action");
+      return 1;
+    }
   } catch (const std::string &Error) {
     std::cerr << Error << "\n";
     if (Out != &std::cout) {
@@ -459,14 +480,6 @@ int main(int argc, char **argv) {
 
   if (Out != &std::cout) {
     delete Out;                               // Close the file
-    
-    // Now that we have generated the result, check to see if we either don't
-    // have the requested file, or if the requested file is different than the
-    // file we generated.  If so, move the generated file over the requested
-    // file.  Otherwise, just remove the file we just generated, so 'make'
-    // doesn't try to regenerate tons of dependencies.
-    //
-    MoveFileOverIfUpdated(OutputFilename+".tmp", OutputFilename);
   }
   return 0;
 }