Fix a bug introduced by the Getelementptr change
[oota-llvm.git] / lib / Target / CBackend / CBackend.cpp
index 4a38db7d42e22e4b33b5f395e43603d70639061d..c54af08e8442130e99a1bd988a0fc9ea97336a3c 100644 (file)
 #include "llvm/iPHINode.h"
 #include "llvm/iOther.h"
 #include "llvm/iOperators.h"
+#include "llvm/Pass.h"
 #include "llvm/SymbolTable.h"
 #include "llvm/SlotCalculator.h"
+#include "llvm/Analysis/FindUsedTypes.h"
 #include "llvm/Support/InstVisitor.h"
 #include "llvm/Support/InstIterator.h"
 #include "Support/StringExtras.h"
@@ -27,121 +29,54 @@ using std::string;
 using std::map;
 using std::ostream;
 
-
-
-// Pass the Type* variable and and the variable name and this prints out the 
-// variable declaration.
-//
-static string calcTypeNameVar(const Type *Ty,
-                              map<const Type *, string> &TypeNames, 
-                              const string &NameSoFar, bool ignoreName = false){
-  if (Ty->isPrimitiveType())
-    switch (Ty->getPrimitiveID()) {
-    case Type::VoidTyID:   return "void " + NameSoFar;
-    case Type::BoolTyID:   return "bool " + NameSoFar;
-    case Type::UByteTyID:  return "unsigned char " + NameSoFar;
-    case Type::SByteTyID:  return "signed char " + NameSoFar;
-    case Type::UShortTyID: return "unsigned short " + NameSoFar;
-    case Type::ShortTyID:  return "short " + NameSoFar;
-    case Type::UIntTyID:   return "unsigned " + NameSoFar;
-    case Type::IntTyID:    return "int " + NameSoFar;
-    case Type::ULongTyID:  return "unsigned long long " + NameSoFar;
-    case Type::LongTyID:   return "signed long long " + NameSoFar;
-    case Type::FloatTyID:  return "float " + NameSoFar;
-    case Type::DoubleTyID: return "double " + NameSoFar;
-    default :
-      std::cerr << "Unknown primitive type: " << Ty << "\n";
-      abort();
-    }
-  
-  // Check to see if the type is named.
-  if (!ignoreName) {
-    map<const Type *, string>::iterator I = TypeNames.find(Ty);
-    if (I != TypeNames.end())
-      return I->second + " " + NameSoFar;
-  }  
-
-  string Result;
-  switch (Ty->getPrimitiveID()) {
-  case Type::FunctionTyID: {
-    const FunctionType *MTy = cast<FunctionType>(Ty);
-    Result += calcTypeNameVar(MTy->getReturnType(), TypeNames, "");
-    Result += " " + NameSoFar + " (";
-    for (FunctionType::ParamTypes::const_iterator
-           I = MTy->getParamTypes().begin(),
-           E = MTy->getParamTypes().end(); I != E; ++I) {
-      if (I != MTy->getParamTypes().begin())
-        Result += ", ";
-      Result += calcTypeNameVar(*I, TypeNames, "");
-    }
-    if (MTy->isVarArg()) {
-      if (!MTy->getParamTypes().empty()) 
-       Result += ", ";
-      Result += "...";
-    }
-    return Result + ")";
-  }
-  case Type::StructTyID: {
-    const StructType *STy = cast<const StructType>(Ty);
-    Result = NameSoFar + " {\n";
-    unsigned indx = 0;
-    for (StructType::ElementTypes::const_iterator
-           I = STy->getElementTypes().begin(),
-           E = STy->getElementTypes().end(); I != E; ++I) {
-      Result += "  " +calcTypeNameVar(*I, TypeNames, "field" + utostr(indx++));
-      Result += ";\n";
-    }
-    return Result + "}";
-  }  
-
-  case Type::PointerTyID:
-    return calcTypeNameVar(cast<const PointerType>(Ty)->getElementType(), 
-                           TypeNames, "*" + NameSoFar);
-  
-  case Type::ArrayTyID: {
-    const ArrayType *ATy = cast<const ArrayType>(Ty);
-    int NumElements = ATy->getNumElements();
-    return calcTypeNameVar(ATy->getElementType(), TypeNames, 
-                           NameSoFar + "[" + itostr(NumElements) + "]");
-  }
-  default:
-    assert(0 && "Unhandled case in getTypeProps!");
-    abort();
-  }
-
-  return Result;
-}
-
 namespace {
-  class CWriter : public InstVisitor<CWriter> {
-    ostreamOut; 
-    SlotCalculator &Table;
+  class CWriter : public Pass, public InstVisitor<CWriter> {
+    ostream &Out; 
+    SlotCalculator *Table;
     const Module *TheModule;
     map<const Type *, string> TypeNames;
     std::set<const Value*> MangledGlobals;
   public:
-    inline CWriter(ostream &o, SlotCalculator &Tab, const Module *M)
-      : Out(o), Table(Tab), TheModule(M) {
+    CWriter(ostream &o) : Out(o) {}
+
+    void getAnalysisUsage(AnalysisUsage &AU) const {
+      AU.setPreservesAll();
+      AU.addRequired<FindUsedTypes>();
     }
-    
-    inline void write(Module *M) { printModule(M); }
 
-    ostream& printType(const Type *Ty, const string &VariableName = "") {
-      return Out << calcTypeNameVar(Ty, TypeNames, VariableName);
+    virtual bool run(Module &M) {
+      // Initialize
+      Table = new SlotCalculator(&M, false);
+      TheModule = &M;
+
+      // Ensure that all structure types have names...
+      bool Changed = nameAllUsedStructureTypes(M);
+
+      // Run...
+      printModule(&M);
+
+      // Free memory...
+      delete Table;
+      TypeNames.clear();
+      MangledGlobals.clear();
+      return false;
     }
 
+    ostream &printType(const Type *Ty, const string &VariableName = "",
+                       bool IgnoreName = false, bool namedContext = true);
+
     void writeOperand(Value *Operand);
     void writeOperandInternal(Value *Operand);
 
     string getValueName(const Value *V);
 
   private :
+    bool nameAllUsedStructureTypes(Module &M);
     void printModule(Module *M);
     void printSymbolTable(const SymbolTable &ST);
     void printGlobal(const GlobalVariable *GV);
-    void printFunctionSignature(const Function *F);
-    void printFunctionDecl(const Function *F); // Print just the forward decl
-    
+    void printFunctionSignature(const Function *F, bool Prototype);
+
     void printFunction(Function *);
 
     void printConstant(Constant *CPV);
@@ -193,7 +128,8 @@ namespace {
     }
     void printBranchToBlock(BasicBlock *CurBlock, BasicBlock *SuccBlock,
                             unsigned Indent);
-    void printIndexingExpr(MemAccessInst &MAI);
+    void printIndexingExpression(Value *Ptr, User::op_iterator I,
+                                 User::op_iterator E);
   };
 }
 
@@ -223,11 +159,109 @@ string CWriter::getValueName(const Value *V) {
            makeNameProper(V->getName());      
   }
 
-  int Slot = Table.getValSlot(V);
+  int Slot = Table->getValSlot(V);
   assert(Slot >= 0 && "Invalid value!");
   return "ltmp_" + itostr(Slot) + "_" + utostr(V->getType()->getUniqueID());
 }
 
+// A pointer type should not use parens around *'s alone, e.g., (**)
+inline bool ptrTypeNameNeedsParens(const string &NameSoFar) {
+  return (NameSoFar.find_last_not_of('*') != std::string::npos);
+}
+
+// Pass the Type* and the variable name and this prints out the variable
+// declaration.
+//
+ostream &CWriter::printType(const Type *Ty, const string &NameSoFar,
+                            bool IgnoreName, bool namedContext) {
+  if (Ty->isPrimitiveType())
+    switch (Ty->getPrimitiveID()) {
+    case Type::VoidTyID:   return Out << "void "               << NameSoFar;
+    case Type::BoolTyID:   return Out << "bool "               << NameSoFar;
+    case Type::UByteTyID:  return Out << "unsigned char "      << NameSoFar;
+    case Type::SByteTyID:  return Out << "signed char "        << NameSoFar;
+    case Type::UShortTyID: return Out << "unsigned short "     << NameSoFar;
+    case Type::ShortTyID:  return Out << "short "              << NameSoFar;
+    case Type::UIntTyID:   return Out << "unsigned "           << NameSoFar;
+    case Type::IntTyID:    return Out << "int "                << NameSoFar;
+    case Type::ULongTyID:  return Out << "unsigned long long " << NameSoFar;
+    case Type::LongTyID:   return Out << "signed long long "   << NameSoFar;
+    case Type::FloatTyID:  return Out << "float "              << NameSoFar;
+    case Type::DoubleTyID: return Out << "double "             << NameSoFar;
+    default :
+      std::cerr << "Unknown primitive type: " << Ty << "\n";
+      abort();
+    }
+  
+  // Check to see if the type is named.
+  if (!IgnoreName) {
+    map<const Type *, string>::iterator I = TypeNames.find(Ty);
+    if (I != TypeNames.end()) {
+      return Out << I->second << " " << NameSoFar;
+    }
+  }  
+
+  switch (Ty->getPrimitiveID()) {
+  case Type::FunctionTyID: {
+    const FunctionType *MTy = cast<FunctionType>(Ty);
+    printType(MTy->getReturnType(), "");
+    Out << " " << NameSoFar << " (";
+
+    for (FunctionType::ParamTypes::const_iterator
+           I = MTy->getParamTypes().begin(),
+           E = MTy->getParamTypes().end(); I != E; ++I) {
+      if (I != MTy->getParamTypes().begin())
+        Out << ", ";
+      printType(*I, "");
+    }
+    if (MTy->isVarArg()) {
+      if (!MTy->getParamTypes().empty()) 
+       Out << ", ";
+      Out << "...";
+    }
+    return Out << ")";
+  }
+  case Type::StructTyID: {
+    const StructType *STy = cast<StructType>(Ty);
+    Out << NameSoFar + " {\n";
+    unsigned Idx = 0;
+    for (StructType::ElementTypes::const_iterator
+           I = STy->getElementTypes().begin(),
+           E = STy->getElementTypes().end(); I != E; ++I) {
+      Out << "  ";
+      printType(*I, "field" + utostr(Idx++));
+      Out << ";\n";
+    }
+    return Out << "}";
+  }  
+
+  case Type::PointerTyID: {
+    const PointerType *PTy = cast<PointerType>(Ty);
+    std::string ptrName = "*" + NameSoFar;
+
+    // Do not need parens around "* NameSoFar" if NameSoFar consists only
+    // of zero or more '*' chars *and* this is not an unnamed pointer type
+    // such as the result type in a cast statement.  Otherwise, enclose in ( ).
+    if (ptrTypeNameNeedsParens(NameSoFar) || !namedContext)
+      ptrName = "(" + ptrName + ")";    // 
+
+    return printType(PTy->getElementType(), ptrName);
+  }
+
+  case Type::ArrayTyID: {
+    const ArrayType *ATy = cast<ArrayType>(Ty);
+    unsigned NumElements = ATy->getNumElements();
+    return printType(ATy->getElementType(),
+                     NameSoFar + "[" + utostr(NumElements) + "]");
+  }
+  default:
+    assert(0 && "Unhandled case in getTypeProps!");
+    abort();
+  }
+
+  return Out;
+}
+
 void CWriter::printConstantArray(ConstantArray *CPA) {
 
   // As a special case, print the array as a string if it is an array of
@@ -286,6 +320,35 @@ void CWriter::printConstantArray(ConstantArray *CPA) {
 void CWriter::printConstant(Constant *CPV) {
   if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) {
     switch (CE->getOpcode()) {
+    case Instruction::Cast:
+      Out << "((";
+      printType(CPV->getType());
+      Out << ")";
+      printConstant(cast<Constant>(CPV->getOperand(0)));
+      Out << ")";
+      return;
+
+    case Instruction::GetElementPtr:
+      Out << "&(";
+      printIndexingExpression(CPV->getOperand(0),
+                              CPV->op_begin()+1, CPV->op_end());
+      Out << ")";
+      return;
+    case Instruction::Add:
+      Out << "(";
+      printConstant(cast<Constant>(CPV->getOperand(0)));
+      Out << " + ";
+      printConstant(cast<Constant>(CPV->getOperand(1)));
+      Out << ")";
+      return;
+    case Instruction::Sub:
+      Out << "(";
+      printConstant(cast<Constant>(CPV->getOperand(0)));
+      Out << " - ";
+      printConstant(cast<Constant>(CPV->getOperand(1)));
+      Out << ")";
+      return;
+
     default:
       std::cerr << "CWriter Error: Unhandled constant expression: "
                 << CE << "\n";
@@ -351,27 +414,27 @@ void CWriter::printConstant(Constant *CPV) {
 }
 
 void CWriter::writeOperandInternal(Value *Operand) {
+  if (Instruction *I = dyn_cast<Instruction>(Operand))
+    if (isInlinableInst(*I)) {
+      // Should we inline this instruction to build a tree?
+      Out << "(";
+      visit(*I);
+      Out << ")";    
+      return;
+    }
+  
   if (Operand->hasName()) {   
     Out << getValueName(Operand);
   } else if (Constant *CPV = dyn_cast<Constant>(Operand)) {
     printConstant(CPV); 
   } else {
-    int Slot = Table.getValSlot(Operand);
+    int Slot = Table->getValSlot(Operand);
     assert(Slot >= 0 && "Malformed LLVM!");
     Out << "ltmp_" << Slot << "_" << Operand->getType()->getUniqueID();
   }
 }
 
 void CWriter::writeOperand(Value *Operand) {
-  if (Instruction *I = dyn_cast<Instruction>(Operand))
-    if (isInlinableInst(*I)) {
-      // Should we inline this instruction to build a tree?
-      Out << "(";
-      visit(*I);
-      Out << ")";    
-      return;
-    }
-
   if (isa<GlobalVariable>(Operand))
     Out << "(&";  // Global variables are references as their addresses by llvm
 
@@ -381,6 +444,36 @@ void CWriter::writeOperand(Value *Operand) {
     Out << ")";
 }
 
+// nameAllUsedStructureTypes - If there are structure types in the module that
+// are used but do not have names assigned to them in the symbol table yet then
+// we assign them names now.
+//
+bool CWriter::nameAllUsedStructureTypes(Module &M) {
+  // Get a set of types that are used by the program...
+  std::set<const Type *> UT = getAnalysis<FindUsedTypes>().getTypes();
+
+  // Loop over the module symbol table, removing types from UT that are already
+  // named.
+  //
+  SymbolTable *MST = M.getSymbolTableSure();
+  if (MST->find(Type::TypeTy) != MST->end())
+    for (SymbolTable::type_iterator I = MST->type_begin(Type::TypeTy),
+           E = MST->type_end(Type::TypeTy); I != E; ++I)
+      UT.erase(cast<Type>(I->second));
+
+  // UT now contains types that are not named.  Loop over it, naming structure
+  // types.
+  //
+  bool Changed = false;
+  for (std::set<const Type *>::const_iterator I = UT.begin(), E = UT.end();
+       I != E; ++I)
+    if (const StructType *ST = dyn_cast<StructType>(*I)) {
+      ((Value*)ST)->setName("unnamed", MST);
+      Changed = true;
+    }
+  return Changed;
+}
+
 void CWriter::printModule(Module *M) {
   // Calculate which global values have names that will collide when we throw
   // away type information.
@@ -401,7 +494,6 @@ void CWriter::printModule(Module *M) {
           FoundNames.insert(I->getName());   // Otherwise, keep track of name
   }
 
-
   // printing stdlib inclusion
   // Out << "#include <stdlib.h>\n";
 
@@ -410,39 +502,61 @@ void CWriter::printModule(Module *M) {
       << "#include <malloc.h>\n"
       << "#include <alloca.h>\n\n"
 
-    // Provide a definition for null if one does not already exist.
+    // Provide a definition for null if one does not already exist,
+    // and for `bool' if not compiling with a C++ compiler.
       << "#ifndef NULL\n#define NULL 0\n#endif\n\n"
-      << "typedef unsigned char bool;\n"
+      << "#ifndef __cplusplus\ntypedef unsigned char bool;\n#endif\n"
+
+      << "\n\n/* Global Declarations */\n";
 
-      << "\n\n/* Global Symbols */\n";
+  // First output all the declarations for the program, because C requires
+  // Functions & globals to be declared before they are used.
+  //
 
   // Loop over the symbol table, emitting all named constants...
   if (M->hasSymbolTable())
     printSymbolTable(*M->getSymbolTable());
 
-  Out << "\n\n/* Global Data */\n";
-  for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) {
-    if (I->hasInternalLinkage()) Out << "static ";
-    printType(I->getType()->getElementType(), getValueName(I));
+  // Global variable declarations...
+  if (!M->gempty()) {
+    Out << "\n/* Global Variable Declarations */\n";
+    for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) {
+      Out << (I->hasExternalLinkage() ? "extern " : "static ");
+      printType(I->getType()->getElementType(), getValueName(I));
+      Out << ";\n";
+    }
+  }
 
-    if (I->hasInitializer()) {
-      Out << " = " ;
-      writeOperand(I->getInitializer());
+  // Function declarations
+  if (!M->empty()) {
+    Out << "\n/* Function Declarations */\n";
+    for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) {
+      printFunctionSignature(I, true);
+      Out << ";\n";
+    }
+  }
+
+  // Output the global variable contents...
+  if (!M->gempty()) {
+    Out << "\n\n/* Global Data */\n";
+    for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) {
+      if (I->hasInternalLinkage()) Out << "static ";
+      printType(I->getType()->getElementType(), getValueName(I));
+      
+      if (I->hasInitializer()) {
+        Out << " = " ;
+        writeOperand(I->getInitializer());
+      }
+      Out << ";\n";
     }
-    Out << ";\n";
   }
 
-  // First output all the declarations of the functions as C requires Functions 
-  // be declared before they are used.
-  //
-  Out << "\n\n/* Function Declarations */\n";
-  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
-    printFunctionDecl(I);
-  
   // Output all of the functions...
-  Out << "\n\n/* Function Bodies */\n";
-  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
-    printFunction(I);
+  if (!M->empty()) {
+    Out << "\n\n/* Function Bodies */\n";
+    for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
+      printFunction(I);
+  }
 }
 
 
@@ -456,9 +570,8 @@ void CWriter::printSymbolTable(const SymbolTable &ST) {
     
     for (; I != End; ++I)
       if (const Type *Ty = dyn_cast<StructType>(I->second)) {
-       string Name = "struct l_" + makeNameProper(I->first);
+        string Name = "struct l_" + makeNameProper(I->first);
         Out << Name << ";\n";
-
         TypeNames.insert(std::make_pair(Ty, Name));
       }
   }
@@ -478,21 +591,15 @@ void CWriter::printSymbolTable(const SymbolTable &ST) {
         else
           Out << "typedef ";
 
-       Out << calcTypeNameVar(Ty, TypeNames, Name, true) << ";\n";
+       printType(Ty, Name, true);
+        Out << ";\n";
       }
     }
   }
 }
 
 
-// printFunctionDecl - Print function declaration
-//
-void CWriter::printFunctionDecl(const Function *F) {
-  printFunctionSignature(F);
-  Out << ";\n";
-}
-
-void CWriter::printFunctionSignature(const Function *F) {
+void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
   if (F->hasInternalLinkage()) Out << "static ";
   
   // Loop over the arguments, printing them...
@@ -504,12 +611,20 @@ void CWriter::printFunctionSignature(const Function *F) {
     
   if (!F->isExternal()) {
     if (!F->aempty()) {
-      printType(F->afront().getType(), getValueName(F->abegin()));
+      string ArgName;
+      if (F->abegin()->hasName() || !Prototype)
+        ArgName = getValueName(F->abegin());
+
+      printType(F->afront().getType(), ArgName);
 
       for (Function::const_aiterator I = ++F->abegin(), E = F->aend();
            I != E; ++I) {
         Out << ", ";
-        printType(I->getType(), getValueName(I));
+        if (I->hasName() || !Prototype)
+          ArgName = getValueName(I);
+        else 
+          ArgName = "";
+        printType(I->getType(), ArgName);
       }
     }
   } else {
@@ -534,9 +649,9 @@ void CWriter::printFunctionSignature(const Function *F) {
 void CWriter::printFunction(Function *F) {
   if (F->isExternal()) return;
 
-  Table.incorporateFunction(F);
+  Table->incorporateFunction(F);
 
-  printFunctionSignature(F);
+  printFunctionSignature(F, false);
   Out << " {\n";
 
   // print local variable information for the function
@@ -584,7 +699,7 @@ void CWriter::printFunction(Function *F) {
   }
   
   Out << "}\n\n";
-  Table.purgeFunction();
+  Table->purgeFunction();
 }
 
 // Specific Instruction type classes... note that all of the casts are
@@ -704,7 +819,7 @@ void CWriter::visitBinaryOperator(Instruction &I) {
 
 void CWriter::visitCastInst(CastInst &I) {
   Out << "(";
-  printType(I.getType());
+  printType(I.getType(), string(""),/*ignoreName*/false, /*namedContext*/false);
   Out << ")";
   writeOperand(I.getOperand(0));
 }
@@ -714,7 +829,8 @@ void CWriter::visitCallInst(CallInst &I) {
   const FunctionType *FTy   = cast<FunctionType>(PTy->getElementType());
   const Type         *RetTy = FTy->getReturnType();
   
-  Out << getValueName(I.getOperand(0)) << "(";
+  writeOperand(I.getOperand(0));
+  Out << "(";
 
   if (I.getNumOperands() > 1) {
     writeOperand(I.getOperand(1));
@@ -760,63 +876,78 @@ void CWriter::visitFreeInst(FreeInst &I) {
   Out << ")";
 }
 
-void CWriter::printIndexingExpr(MemAccessInst &MAI) {
-  MemAccessInst::op_iterator I = MAI.idx_begin(), E = MAI.idx_end();
+void CWriter::printIndexingExpression(Value *Ptr, User::op_iterator I,
+                                      User::op_iterator E) {
+  bool HasImplicitAddress = false;
+  // If accessing a global value with no indexing, avoid *(&GV) syndrome
+  if (GlobalValue *V = dyn_cast<GlobalValue>(Ptr)) {
+    HasImplicitAddress = true;
+  } else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Ptr)) {
+    HasImplicitAddress = true;
+    Ptr = CPR->getValue();         // Get to the global...
+  }
+
   if (I == E) {
-    // If accessing a global value with no indexing, avoid *(&GV) syndrome
-    if (GlobalValue *V = dyn_cast<GlobalValue>(MAI.getPointerOperand())) {
-      writeOperandInternal(V);
-      return;
-    }
+    if (!HasImplicitAddress)
+      Out << "*";  // Implicit zero first argument: '*x' is equivalent to 'x[0]'
 
-    Out << "*";  // Implicit zero first argument: '*x' is equivalent to 'x[0]'
+    writeOperandInternal(Ptr);
+    return;
   }
 
-  writeOperand(MAI.getPointerOperand());
+  const Constant *CI = dyn_cast<Constant>(I->get());
+  if (HasImplicitAddress && (!CI || !CI->isNullValue()))
+    Out << "(&";
+
+  writeOperandInternal(Ptr);
 
-  if (I == E) return;
+  if (HasImplicitAddress && (!CI || !CI->isNullValue()))
+    Out << ")";
 
   // Print out the -> operator if possible...
-  const Constant *CI = dyn_cast<Constant>(I->get());
-  if (CI && CI->isNullValue() && I+1 != E &&
-      (*(I+1))->getType() == Type::UByteTy) {
-    Out << "->field" << cast<ConstantUInt>(*(I+1))->getValue();
-    I += 2;
+  if (CI && CI->isNullValue() && I+1 != E) {
+    if ((*(I+1))->getType() == Type::UByteTy) {
+      Out << (HasImplicitAddress ? "." : "->");
+      Out << "field" << cast<ConstantUInt>(*(I+1))->getValue();
+      I += 2;
+    } else {  // First array index of 0: Just skip it
+      ++I;
+    }
   }
-    
+
   for (; I != E; ++I)
-    if ((*I)->getType() == Type::UIntTy) {
-      Out << "[";
+    if ((*I)->getType() == Type::LongTy) {
+      Out << "[((int) (";                 // sign-extend from 32 (to 64) bits
       writeOperand(*I);
-      Out << "]";
+      Out << " * sizeof(";
+      printType(cast<PointerType>(Ptr->getType())->getElementType());
+      Out << "))) / sizeof(";
+      printType(cast<PointerType>(Ptr->getType())->getElementType());
+      Out << ")]";
     } else {
       Out << ".field" << cast<ConstantUInt>(*I)->getValue();
     }
 }
 
 void CWriter::visitLoadInst(LoadInst &I) {
-  printIndexingExpr(I);
+  Out << "*";
+  writeOperand(I.getOperand(0));
 }
 
 void CWriter::visitStoreInst(StoreInst &I) {
-  printIndexingExpr(I);
+  Out << "*";
+  writeOperand(I.getPointerOperand());
   Out << " = ";
   writeOperand(I.getOperand(0));
 }
 
 void CWriter::visitGetElementPtrInst(GetElementPtrInst &I) {
   Out << "&";
-  printIndexingExpr(I);
+  printIndexingExpression(I.getPointerOperand(), I.idx_begin(), I.idx_end());
 }
 
 //===----------------------------------------------------------------------===//
 //                       External Interface declaration
 //===----------------------------------------------------------------------===//
 
-void WriteToC(const Module *M, ostream &Out) {
-  assert(M && "You can't write a null module!!");
-  SlotCalculator SlotTable(M, false);
-  CWriter W(Out, SlotTable, M);
-  W.write((Module*)M);
-  Out.flush();
-}
+Pass *createWriteToCPass(std::ostream &o) { return new CWriter(o); }