Added name-mangling routines for future use.
[oota-llvm.git] / lib / VMCore / AsmWriter.cpp
index 24d7cc8e7f30ad292faf0e1a62ba48e0eaba5e16..13e01190808ea5c8081a833be79c097fd5ebb854 100644 (file)
@@ -19,6 +19,7 @@
 #include "llvm/ConstPoolVals.h"
 #include "llvm/iOther.h"
 #include "llvm/iMemory.h"
+#include "llvm/iTerminators.h"
 #include "llvm/Support/STLExtras.h"
 #include "llvm/SymbolTable.h"
 #include <algorithm>
@@ -35,24 +36,26 @@ ostream &WriteAsOperand(ostream &Out, const Value *V, bool PrintType,
   if (PrintName && V->hasName()) {
     Out << " %" << V->getName();
   } else {
-    if (const ConstPoolVal *CPV = V->castConstant()) {
+    if (const ConstPoolVal *CPV = dyn_cast<const ConstPoolVal>(V)) {
       Out << " " << CPV->getStrValue();
     } else {
       int Slot;
       if (Table) {
        Slot = Table->getValSlot(V);
       } else {
-       if (const Type *Ty = V->castType()) {
+       if (const Type *Ty = dyn_cast<const Type>(V)) {
          return Out << " " << Ty;
-       } else if (const MethodArgument *MA = V->castMethodArgument()) {
+       } else if (const MethodArgument *MA =dyn_cast<const MethodArgument>(V)){
          Table = new SlotCalculator(MA->getParent(), true);
-       } else if (const Instruction *I = V->castInstruction()) {
+       } else if (const Instruction *I = dyn_cast<const Instruction>(V)) {
          Table = new SlotCalculator(I->getParent()->getParent(), true);
-       } else if (const BasicBlock *BB = V->castBasicBlock()) {
+       } else if (const BasicBlock *BB = dyn_cast<const BasicBlock>(V)) {
          Table = new SlotCalculator(BB->getParent(), true);
-       } else if (const Method *Meth = V->castMethod()) {
+       } else if (const GlobalVariable *GV =dyn_cast<const GlobalVariable>(V)){
+         Table = new SlotCalculator(GV->getParent(), true);
+       } else if (const Method *Meth = dyn_cast<const Method>(V)) {
          Table = new SlotCalculator(Meth, true);
-       } else if (const Module *Mod  = V->castModule()) {
+       } else if (const Module *Mod  = dyn_cast<const Module>(V)) {
          Table = new SlotCalculator(Mod, true);
        } else {
          return Out << "BAD VALUE TYPE!";
@@ -95,6 +98,11 @@ private :
   void processInstruction(const Instruction *I);
   
   void writeOperand(const Value *Op, bool PrintType, bool PrintName = true);
+
+  // printInfoComment - Print a little comment after the instruction indicating
+  // which slot it occupies.
+  void printInfoComment(const Value *V);
+
 };
 
 
@@ -129,6 +137,7 @@ void AssemblyWriter::processGlobal(const GlobalVariable *GV) {
   if (GV->hasInitializer())
     writeOperand(GV->getInitializer(), false, false);
 
+  printInfoComment(GV);
   Out << endl;
 }
 
@@ -143,9 +152,9 @@ void AssemblyWriter::processSymbolTable(const SymbolTable &ST) {
     
     for (; I != End; ++I) {
       const Value *V = I->second;
-      if (const ConstPoolVal *CPV = V->castConstant()) {
+      if (const ConstPoolVal *CPV = dyn_cast<const ConstPoolVal>(V)) {
        processConstant(CPV);
-      } else if (const Type *Ty = V->castType()) {
+      } else if (const Type *Ty = dyn_cast<const Type>(V)) {
        Out << "\t%" << I->first << " = type " << Ty->getDescription() << endl;
       }
     }
@@ -187,12 +196,22 @@ void AssemblyWriter::processMethod(const Method *M) {
   Table.incorporateMethod(M);
 
   // Loop over the arguments, processing them...
-  for_each(M->getArgumentList().begin(), M->getArgumentList().end(),
-          bind_obj(this, &AssemblyWriter::processMethodArgument));
+  const MethodType *MT = cast<const MethodType>(M->getMethodType());
 
+  if (!M->isExternal()) {
+    for_each(M->getArgumentList().begin(), M->getArgumentList().end(),
+            bind_obj(this, &AssemblyWriter::processMethodArgument));
+  } else {
+    // Loop over the arguments, processing them...
+    const MethodType *MT = cast<const MethodType>(M->getMethodType());
+    for (MethodType::ParamTypes::const_iterator I = MT->getParamTypes().begin(),
+          E = MT->getParamTypes().end(); I != E; ++I) {
+      if (I != MT->getParamTypes().begin()) Out << ", ";
+      Out << *I;
+    }
+  }
 
   // Finish printing arguments...
-  const MethodType *MT = (const MethodType*)M->getType();
   if (MT->isVarArg()) {
     if (MT->getParamTypes().size()) Out << ", ";
     Out << "...";  // Output varargs portion of signature!
@@ -253,6 +272,23 @@ void AssemblyWriter::processBasicBlock(const BasicBlock *BB) {
           bind_obj(this, &AssemblyWriter::processInstruction));
 }
 
+
+// printInfoComment - Print a little comment after the instruction indicating
+// which slot it occupies.
+//
+void AssemblyWriter::printInfoComment(const Value *V) {
+  if (V->getType() != Type::VoidTy) {
+    Out << "\t\t; <" << V->getType() << ">";
+
+    if (!V->hasName()) {
+      int Slot = Table.getValSlot(V); // Print out the def slot taken...
+      if (Slot >= 0) Out << ":" << Slot;
+      else Out << ":<badref>";
+    }
+    Out << "\t[#uses=" << V->use_size() << "]";  // Output # uses
+  }
+}
+
 // processInstruction - This member is called for each Instruction in a methd.
 //
 void AssemblyWriter::processInstruction(const Instruction *I) {
@@ -287,7 +323,7 @@ void AssemblyWriter::processInstruction(const Instruction *I) {
       writeOperand(I->getOperand(op+1), true);
     }
     Out << "\n\t]";
-  } else if (I->isPHINode()) {
+  } else if (isa<PHINode>(I)) {
     Out << " " << Operand->getType();
 
     Out << " [";  writeOperand(Operand, false); Out << ",";
@@ -297,9 +333,10 @@ void AssemblyWriter::processInstruction(const Instruction *I) {
       writeOperand(I->getOperand(op  ), false); Out << ",";
       writeOperand(I->getOperand(op+1), false); Out << " ]";
     }
-  } else if (I->getOpcode() == Instruction::Ret && !Operand) {
+  } else if (isa<ReturnInst>(I) && !Operand) {
     Out << " void";
-  } else if (I->getOpcode() == Instruction::Call) {
+  } else if (isa<CallInst>(I)) {
+    // TODO: Should try to print out short form of the Call instruction
     writeOperand(Operand, true);
     Out << "(";
     if (I->getNumOperands() > 1) writeOperand(I->getOperand(1), true);
@@ -309,14 +346,29 @@ void AssemblyWriter::processInstruction(const Instruction *I) {
     }
 
     Out << " )";
+  } else if (const InvokeInst *II = dyn_cast<InvokeInst>(I)) {
+    // TODO: Should try to print out short form of the Invoke instruction
+    writeOperand(Operand, true);
+    Out << "(";
+    if (I->getNumOperands() > 3) writeOperand(I->getOperand(3), true);
+    for (unsigned op = 4, Eop = I->getNumOperands(); op < Eop; ++op) {
+      Out << ",";
+      writeOperand(I->getOperand(op), true);
+    }
+
+    Out << " )\n\t\t\tto";
+    writeOperand(II->getNormalDest(), true);
+    Out << " except";
+    writeOperand(II->getExceptionalDest(), true);
+
   } else if (I->getOpcode() == Instruction::Malloc || 
             I->getOpcode() == Instruction::Alloca) {
-    Out << " " << ((const PointerType*)I->getType())->getValueType();
+    Out << " " << cast<const PointerType>(I->getType())->getValueType();
     if (I->getNumOperands()) {
       Out << ",";
       writeOperand(I->getOperand(0), true);
     }
-  } else if (I->getOpcode() == Instruction::Cast) {
+  } else if (isa<CastInst>(I)) {
     writeOperand(Operand, true);
     Out << " to " << I->getType();
   } else if (Operand) {   // Print the normal way...
@@ -335,6 +387,9 @@ void AssemblyWriter::processInstruction(const Instruction *I) {
       }
     }
 
+    // Shift Left & Right print both types even for Ubyte LHS
+    if (isa<ShiftInst>(I)) PrintAllTypes = true;
+
     if (!PrintAllTypes)
       Out << " " << I->getOperand(0)->getType();
 
@@ -344,19 +399,7 @@ void AssemblyWriter::processInstruction(const Instruction *I) {
     }
   }
 
-  // Print a little comment after the instruction indicating which slot it
-  // occupies.
-  //
-  if (I->getType() != Type::VoidTy) {
-    Out << "\t\t; <" << I->getType() << ">";
-
-    if (!I->hasName()) {
-      int Slot = Table.getValSlot(I); // Print out the def slot taken...
-      if (Slot >= 0) Out << ":" << Slot;
-      else Out << ":<badref>";
-    }
-    Out << "\t[#uses=" << I->use_size() << "]";  // Output # uses
-  }
+  printInfoComment(I);
   Out << endl;
 }