AsmWriter.cpp revision 7a716addedc4938fa0ec6b77e5eeaced6eafc5d0
18da78afce3609f8ac31bef9d1310744a47bbd0ccChris Lattner//===-- AsmWriter.cpp - Printing LLVM as an assembly file -----------------===//
2009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
3009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// This library implements the functionality defined in llvm/Assembly/Writer.h
4009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
502b9399baef2afc1a0c8c83152d2f28145658bbcChris Lattner// Note that these routines must be extremely tolerant of various errors in the
602b9399baef2afc1a0c8c83152d2f28145658bbcChris Lattner// LLVM code, because of of the primary uses of it is for debugging
702b9399baef2afc1a0c8c83152d2f28145658bbcChris Lattner// transformations.
802b9399baef2afc1a0c8c83152d2f28145658bbcChris Lattner//
9009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// TODO: print out the type name instead of the full type if a particular type
1002b9399baef2afc1a0c8c83152d2f28145658bbcChris Lattner// is in the symbol table...
11009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
12009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===//
13009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
14da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner#include "llvm/Assembly/CachedWriter.h"
1575cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner#include "llvm/Assembly/Writer.h"
16b579400cd72f274607f4964a9649ea4d38e04c46Chris Lattner#include "llvm/SlotCalculator.h"
17009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Module.h"
1879df7c0aaa18129e55968c8783ef8346807bd4afChris Lattner#include "llvm/Function.h"
1970cc3397f84c2e1fd69c059a0ef89e398e847b00Chris Lattner#include "llvm/GlobalVariable.h"
20009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/BasicBlock.h"
21e9bb2df410f7a22decad9a883f7139d5857c1520Chris Lattner#include "llvm/ConstantVals.h"
22009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/iMemory.h"
23e02fa8551d20081534afa46e0976811687e5183aChris Lattner#include "llvm/iTerminators.h"
247061dc50b2513731d7b346ab16183cda4a44619fChris Lattner#include "llvm/iPHINode.h"
257061dc50b2513731d7b346ab16183cda4a44619fChris Lattner#include "llvm/iOther.h"
26007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner#include "llvm/SymbolTable.h"
2773e214244f2403b5ba0ef81b8839600f3c8ffebcChris Lattner#include "llvm/Argument.h"
28cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#include "Support/StringExtras.h"
29cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#include "Support/STLExtras.h"
30007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner#include <algorithm>
31c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner#include <map>
32697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerusing std::string;
33697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerusing std::map;
34697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerusing std::vector;
35697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerusing std::ostream;
36c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner
377a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattnerstatic void WriteAsOperandInternal(ostream &Out, const Value *V, bool PrintName,
387a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner                                   map<const Type *, string> &TypeTable,
397a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner                                   SlotCalculator *Table);
407a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner
41207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattnerstatic const Module *getModuleFromVal(const Value *V) {
4273e214244f2403b5ba0ef81b8839600f3c8ffebcChris Lattner  if (const Argument *MA = dyn_cast<const Argument>(V))
43207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    return MA->getParent() ? MA->getParent()->getParent() : 0;
44207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  else if (const BasicBlock *BB = dyn_cast<const BasicBlock>(V))
45207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    return BB->getParent() ? BB->getParent()->getParent() : 0;
46207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  else if (const Instruction *I = dyn_cast<const Instruction>(V)) {
4779df7c0aaa18129e55968c8783ef8346807bd4afChris Lattner    const Function *M = I->getParent() ? I->getParent()->getParent() : 0;
48207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    return M ? M->getParent() : 0;
4979df7c0aaa18129e55968c8783ef8346807bd4afChris Lattner  } else if (const GlobalValue *GV = dyn_cast<const GlobalValue>(V))
50207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    return GV->getParent();
51207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  else if (const Module *Mod  = dyn_cast<const Module>(V))
52207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    return Mod;
53207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  return 0;
54207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner}
55207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
56c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattnerstatic SlotCalculator *createSlotCalculator(const Value *V) {
57c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  assert(!isa<Type>(V) && "Can't create an SC for a type!");
5873e214244f2403b5ba0ef81b8839600f3c8ffebcChris Lattner  if (const Argument *FA = dyn_cast<const Argument>(V)) {
5979df7c0aaa18129e55968c8783ef8346807bd4afChris Lattner    return new SlotCalculator(FA->getParent(), true);
60c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  } else if (const Instruction *I = dyn_cast<const Instruction>(V)) {
61c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    return new SlotCalculator(I->getParent()->getParent(), true);
62c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  } else if (const BasicBlock *BB = dyn_cast<const BasicBlock>(V)) {
63c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    return new SlotCalculator(BB->getParent(), true);
6479df7c0aaa18129e55968c8783ef8346807bd4afChris Lattner  } else if (const GlobalVariable *GV = dyn_cast<const GlobalVariable>(V)){
65c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    return new SlotCalculator(GV->getParent(), true);
6679df7c0aaa18129e55968c8783ef8346807bd4afChris Lattner  } else if (const Function *Func = dyn_cast<const Function>(V)) {
6779df7c0aaa18129e55968c8783ef8346807bd4afChris Lattner    return new SlotCalculator(Func, true);
68c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  } else if (const Module *Mod  = dyn_cast<const Module>(V)) {
69c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    return new SlotCalculator(Mod, true);
70c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  }
71c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  return 0;
72c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner}
73009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
74207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
75207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner// If the module has a symbol table, take all global types and stuff their
76207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner// names into the TypeNames map.
77207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner//
78207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattnerstatic void fillTypeNameTable(const Module *M,
79207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner                              map<const Type *, string> &TypeNames) {
80207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  if (M && M->hasSymbolTable()) {
81207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    const SymbolTable *ST = M->getSymbolTable();
82207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    SymbolTable::const_iterator PI = ST->find(Type::TypeTy);
83207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    if (PI != ST->end()) {
84207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner      SymbolTable::type_const_iterator I = PI->second.begin();
85207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner      for (; I != PI->second.end(); ++I) {
86207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner        // As a heuristic, don't insert pointer to primitive types, because
87207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner        // they are used too often to have a single useful name.
88207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner        //
89207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner        const Type *Ty = cast<const Type>(I->second);
90207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner        if (!isa<PointerType>(Ty) ||
917a1767520611d9ff6face702068de858e1cadf2cChris Lattner            !cast<PointerType>(Ty)->getElementType()->isPrimitiveType())
92697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner          TypeNames.insert(std::make_pair(Ty, "%"+I->first));
93207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner      }
94207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    }
95207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  }
96207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner}
97207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
98207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
99207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
100207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattnerstatic string calcTypeName(const Type *Ty, vector<const Type *> &TypeStack,
101207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner                           map<const Type *, string> &TypeNames) {
102207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  if (Ty->isPrimitiveType()) return Ty->getDescription();  // Base case
103207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
104207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  // Check to see if the type is named.
105207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  map<const Type *, string>::iterator I = TypeNames.find(Ty);
106207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  if (I != TypeNames.end()) return I->second;
107207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
108207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  // Check to see if the Type is already on the stack...
109207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  unsigned Slot = 0, CurSize = TypeStack.size();
110207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  while (Slot < CurSize && TypeStack[Slot] != Ty) ++Slot; // Scan for type
111207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
112207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  // This is another base case for the recursion.  In this case, we know
113207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  // that we have looped back to a type that we have previously visited.
114207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  // Generate the appropriate upreference to handle this.
115207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  //
116207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  if (Slot < CurSize)
117207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    return "\\" + utostr(CurSize-Slot);       // Here's the upreference
118207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
119207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  TypeStack.push_back(Ty);    // Recursive case: Add us to the stack..
120207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
121207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  string Result;
122207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  switch (Ty->getPrimitiveID()) {
1236bfd6a578a3a4fa95c585c988ee712ba880f9923Chris Lattner  case Type::FunctionTyID: {
1242761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner    const FunctionType *FTy = cast<const FunctionType>(Ty);
1252761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner    Result = calcTypeName(FTy->getReturnType(), TypeStack, TypeNames) + " (";
1266bfd6a578a3a4fa95c585c988ee712ba880f9923Chris Lattner    for (FunctionType::ParamTypes::const_iterator
1272761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner           I = FTy->getParamTypes().begin(),
1282761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner           E = FTy->getParamTypes().end(); I != E; ++I) {
1292761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner      if (I != FTy->getParamTypes().begin())
130207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner        Result += ", ";
131207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner      Result += calcTypeName(*I, TypeStack, TypeNames);
132207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    }
1332761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner    if (FTy->isVarArg()) {
1342761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner      if (!FTy->getParamTypes().empty()) Result += ", ";
135207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner      Result += "...";
136207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    }
137207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    Result += ")";
138207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    break;
139207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  }
140207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  case Type::StructTyID: {
141207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    const StructType *STy = cast<const StructType>(Ty);
142207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    Result = "{ ";
143207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    for (StructType::ElementTypes::const_iterator
144207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner           I = STy->getElementTypes().begin(),
145207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner           E = STy->getElementTypes().end(); I != E; ++I) {
146207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner      if (I != STy->getElementTypes().begin())
147207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner        Result += ", ";
148207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner      Result += calcTypeName(*I, TypeStack, TypeNames);
149207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    }
150207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    Result += " }";
151207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    break;
152207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  }
153207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  case Type::PointerTyID:
1547a1767520611d9ff6face702068de858e1cadf2cChris Lattner    Result = calcTypeName(cast<const PointerType>(Ty)->getElementType(),
15502b9399baef2afc1a0c8c83152d2f28145658bbcChris Lattner                          TypeStack, TypeNames) + "*";
156207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    break;
157207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  case Type::ArrayTyID: {
158207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    const ArrayType *ATy = cast<const ArrayType>(Ty);
159ff5c296498b3b1182e8d5e2515d0c15a7b558d4bChris Lattner    Result = "[" + utostr(ATy->getNumElements()) + " x ";
160207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    Result += calcTypeName(ATy->getElementType(), TypeStack, TypeNames) + "]";
161207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    break;
162207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  }
163207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  default:
164207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    assert(0 && "Unhandled case in getTypeProps!");
165207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    Result = "<error>";
166207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  }
167207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
168207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  TypeStack.pop_back();       // Remove self from stack...
169207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  return Result;
170207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner}
171207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
172207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
173207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner// printTypeInt - The internal guts of printing out a type that has a
174207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner// potentially named portion.
175207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner//
176207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattnerstatic ostream &printTypeInt(ostream &Out, const Type *Ty,
177207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner                             map<const Type *, string> &TypeNames) {
178207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  // Primitive types always print out their description, regardless of whether
179207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  // they have been named or not.
180207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  //
181207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  if (Ty->isPrimitiveType()) return Out << Ty->getDescription();
182207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
183207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  // Check to see if the type is named.
184207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  map<const Type *, string>::iterator I = TypeNames.find(Ty);
185207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  if (I != TypeNames.end()) return Out << I->second;
186207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
187207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  // Otherwise we have a type that has not been named but is a derived type.
188207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  // Carefully recurse the type hierarchy to print out any contained symbolic
189207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  // names.
190207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  //
191207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  vector<const Type *> TypeStack;
192207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  string TypeName = calcTypeName(Ty, TypeStack, TypeNames);
193697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  TypeNames.insert(std::make_pair(Ty, TypeName));//Cache type name for later use
194207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  return Out << TypeName;
195207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner}
196207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
197e51e03b3c649ed9419bd0e920c03ef9023ccee48Chris Lattner
198207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner// WriteTypeSymbolic - This attempts to write the specified type as a symbolic
199207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner// type, iff there is an entry in the modules symbol table for the specified
200207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner// type or one of it's component types.  This is slower than a simple x << Type;
201207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner//
202207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattnerostream &WriteTypeSymbolic(ostream &Out, const Type *Ty, const Module *M) {
203207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  Out << " ";
204207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
205207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  // If they want us to print out a type, attempt to make it symbolic if there
206207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  // is a symbol table in the module...
207207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  if (M && M->hasSymbolTable()) {
208207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    map<const Type *, string> TypeNames;
209207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    fillTypeNameTable(M, TypeNames);
210207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
2117b8660d72f35f5ddea0c81eb71f2bdd60fd62832Chris Lattner    return printTypeInt(Out, Ty, TypeNames);
212207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  } else {
2137b8660d72f35f5ddea0c81eb71f2bdd60fd62832Chris Lattner    return Out << Ty->getDescription();
214207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner  }
215207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner}
216207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
2177a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattnerstatic void WriteConstantInt(ostream &Out, const Constant *CV, bool PrintName,
2187a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner                             map<const Type *, string> &TypeTable,
2197a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner                             SlotCalculator *Table) {
2207a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner  if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
2217a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner    const Type *SubType = CA->getType()->getElementType();
2227a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner    if (SubType == Type::SByteTy) {
2237a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner      Out << CV->getStrValue();   // Output string format if possible...
2247a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner    } else {
2257a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner      Out << "[";
2267a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner      if (CA->getNumOperands()) {
2277a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner        Out << " ";
2287a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner        printTypeInt(Out, SubType, TypeTable);
2297a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner        WriteAsOperandInternal(Out, CA->getOperand(0),
2307a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner                               PrintName, TypeTable, Table);
2317a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner        for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
2327a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner          Out << ", ";
2337a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner          printTypeInt(Out, SubType, TypeTable);
2347a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner          WriteAsOperandInternal(Out, CA->getOperand(i), PrintName,
2357a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner                                 TypeTable, Table);
2367a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner        }
2377a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner      }
2387a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner      Out << " ]";
2397a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner    }
2407a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner  } else if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
2417a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner    Out << "{";
2427a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner    if (CS->getNumOperands()) {
2437a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner      Out << " ";
2447a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner      printTypeInt(Out, CS->getOperand(0)->getType(), TypeTable);
2457a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner
2467a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner      WriteAsOperandInternal(Out, CS->getOperand(0),
2477a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner                             PrintName, TypeTable, Table);
2487a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner
2497a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner      for (unsigned i = 1; i < CS->getNumOperands(); i++) {
2507a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner        Out << ", ";
2517a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner        printTypeInt(Out, CS->getOperand(i)->getType(), TypeTable);
2527a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner
2537a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner        WriteAsOperandInternal(Out, CS->getOperand(i),
2547a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner                               PrintName, TypeTable, Table);
2557a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner      }
2567a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner    }
2577a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner
2587a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner    Out << " }";
2597a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner  } else if (isa<ConstantPointerNull>(CV)) {
2607a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner    Out << "null";
2617a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner
2627a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner    // FIXME: Handle ConstantPointerRef + lots of others...
2637a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner  } else {
2647a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner    Out << CV->getStrValue();
2657a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner  }
2667a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner}
2677a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner
2687a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner
2697a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner// WriteAsOperand - Write the name of the specified value out to the specified
2707a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner// ostream.  This can be useful when you just want to print int %reg126, not the
2717a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner// whole instruction that generated it.
2727a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner//
2737a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattnerstatic void WriteAsOperandInternal(ostream &Out, const Value *V, bool PrintName,
2747a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner                                   map<const Type *, string> &TypeTable,
2757a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner                                   SlotCalculator *Table) {
2767a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner  Out << " ";
2777a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner  if (PrintName && V->hasName()) {
2787a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner    Out << "%" << V->getName();
2797a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner  } else {
2807a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner    if (const Constant *CV = dyn_cast<const Constant>(V)) {
2817a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner      WriteConstantInt(Out, CV, PrintName, TypeTable, Table);
2827a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner    } else {
2837a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner      int Slot;
2847a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner      if (Table) {
2857a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner	Slot = Table->getValSlot(V);
2867a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner      } else {
2877a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner        if (const Type *Ty = dyn_cast<const Type>(V)) {
2887a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner          Out << Ty->getDescription();
2897a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner          return;
2907a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner        }
2917a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner
2927a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner        Table = createSlotCalculator(V);
2937a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner        if (Table == 0) { Out << "BAD VALUE TYPE!"; return; }
2947a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner
2957a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner	Slot = Table->getValSlot(V);
2967a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner	delete Table;
2977a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner      }
2987a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner      if (Slot >= 0)  Out << "%" << Slot;
2997a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner      else if (PrintName)
3007a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner        Out << "<badref>";     // Not embeded into a location?
3017a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner    }
3027a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner  }
3037a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner}
3047a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner
3057a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner
306207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
307207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner// WriteAsOperand - Write the name of the specified value out to the specified
308207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner// ostream.  This can be useful when you just want to print int %reg126, not the
309207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner// whole instruction that generated it.
310207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner//
311207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattnerostream &WriteAsOperand(ostream &Out, const Value *V, bool PrintType,
312207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner			bool PrintName, SlotCalculator *Table) {
3137a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner  map<const Type *, string> TypeNames;
3147a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner  const Module *M = getModuleFromVal(V);
3157a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner
3167a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner  if (M && M->hasSymbolTable())
3177a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner    fillTypeNameTable(M, TypeNames);
318207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner
3197a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner  if (PrintType)
3207a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner    printTypeInt(Out, V->getType(), TypeNames);
3217a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner
3227a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner  WriteAsOperandInternal(Out, V, PrintName, TypeNames, Table);
323622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner  return Out;
324622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner}
325622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner
326622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner
327d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattner
328007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnerclass AssemblyWriter {
329009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  ostream &Out;
330009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  SlotCalculator &Table;
331c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  const Module *TheModule;
332c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  map<const Type *, string> TypeNames;
333009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerpublic:
334c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  inline AssemblyWriter(ostream &o, SlotCalculator &Tab, const Module *M)
335c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    : Out(o), Table(Tab), TheModule(M) {
336c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner
337c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    // If the module has a symbol table, take all global types and stuff their
338c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    // names into the TypeNames map.
339c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    //
340207b5bc6a15e12a87c3c861da680b8b23559a34cChris Lattner    fillTypeNameTable(M, TypeNames);
341009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
342009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
343c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  inline void write(const Module *M)         { printModule(M);      }
344c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  inline void write(const GlobalVariable *G) { printGlobal(G);      }
34579df7c0aaa18129e55968c8783ef8346807bd4afChris Lattner  inline void write(const Function *F)       { printFunction(F);    }
346c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  inline void write(const BasicBlock *BB)    { printBasicBlock(BB); }
347c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  inline void write(const Instruction *I)    { printInstruction(I); }
348e9bb2df410f7a22decad9a883f7139d5857c1520Chris Lattner  inline void write(const Constant *CPV)     { printConstant(CPV);  }
349da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner  inline void write(const Type *Ty)          { printType(Ty);       }
350009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
351009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerprivate :
352c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  void printModule(const Module *M);
353c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  void printSymbolTable(const SymbolTable &ST);
354e9bb2df410f7a22decad9a883f7139d5857c1520Chris Lattner  void printConstant(const Constant *CPV);
355c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  void printGlobal(const GlobalVariable *GV);
35679df7c0aaa18129e55968c8783ef8346807bd4afChris Lattner  void printFunction(const Function *F);
35773e214244f2403b5ba0ef81b8839600f3c8ffebcChris Lattner  void printArgument(const Argument *FA);
358c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  void printBasicBlock(const BasicBlock *BB);
359c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  void printInstruction(const Instruction *I);
3602761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner
3612761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner  // printType - Go to extreme measures to attempt to print out a short,
3622761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner  // symbolic version of a type name.
3632761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner  //
3642761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner  ostream &printType(const Type *Ty) {
3652761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner    return printTypeInt(Out, Ty, TypeNames);
3662761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner  }
3672761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner
3682761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner  // printTypeAtLeastOneLevel - Print out one level of the possibly complex type
3692761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner  // without considering any symbolic types that we may have equal to it.
3702761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner  //
3712761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner  ostream &printTypeAtLeastOneLevel(const Type *Ty);
372c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner
373009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  void writeOperand(const Value *Op, bool PrintType, bool PrintName = true);
374e02fa8551d20081534afa46e0976811687e5183aChris Lattner
375e02fa8551d20081534afa46e0976811687e5183aChris Lattner  // printInfoComment - Print a little comment after the instruction indicating
376e02fa8551d20081534afa46e0976811687e5183aChris Lattner  // which slot it occupies.
377e02fa8551d20081534afa46e0976811687e5183aChris Lattner  void printInfoComment(const Value *V);
378009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner};
379009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
380009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
3812761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner// printTypeAtLeastOneLevel - Print out one level of the possibly complex type
3822761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner// without considering any symbolic types that we may have equal to it.
3832761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner//
3842761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattnerostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) {
3852761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner  if (FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
3862761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner    printType(FTy->getReturnType()) << " (";
3872761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner    for (FunctionType::ParamTypes::const_iterator
3882761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner           I = FTy->getParamTypes().begin(),
3892761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner           E = FTy->getParamTypes().end(); I != E; ++I) {
3902761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner      if (I != FTy->getParamTypes().begin())
3912761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner        Out << ", ";
3927a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner      printType(*I);
3932761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner    }
3942761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner    if (FTy->isVarArg()) {
3952761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner      if (!FTy->getParamTypes().empty()) Out << ", ";
3962761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner      Out << "...";
3972761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner    }
3982761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner    Out << ")";
3992761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner  } else if (StructType *STy = dyn_cast<StructType>(Ty)) {
4002761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner    Out << "{ ";
4012761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner    for (StructType::ElementTypes::const_iterator
4022761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner           I = STy->getElementTypes().begin(),
4032761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner           E = STy->getElementTypes().end(); I != E; ++I) {
4042761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner      if (I != STy->getElementTypes().begin())
4052761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner        Out << ", ";
4062761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner      printType(*I);
4072761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner    }
4082761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner    Out << " }";
4092761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner  } else if (PointerType *PTy = dyn_cast<PointerType>(Ty)) {
4102761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner    printType(PTy->getElementType()) << "*";
4112761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner  } else if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
4122761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner    Out << "[" << ATy->getNumElements() << " x ";
4132761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner    printType(ATy->getElementType()) << "]";
4142761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner  } else {
4152761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner    assert(Ty->isPrimitiveType() && "Unknown derived type!");
4162761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner    printType(Ty);
4172761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner  }
4182761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner  return Out;
4192761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner}
4202761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner
4212761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner
422007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnervoid AssemblyWriter::writeOperand(const Value *Operand, bool PrintType,
423007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner				  bool PrintName) {
424c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  if (PrintType) { Out << " "; printType(Operand->getType()); }
4257a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner  WriteAsOperandInternal(Out, Operand, PrintName, TypeNames, &Table);
426007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner}
427007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
428007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
429c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattnervoid AssemblyWriter::printModule(const Module *M) {
430007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  // Loop over the symbol table, emitting all named constants...
431007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  if (M->hasSymbolTable())
432c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    printSymbolTable(*M->getSymbolTable());
43370cc3397f84c2e1fd69c059a0ef89e398e847b00Chris Lattner
43470cc3397f84c2e1fd69c059a0ef89e398e847b00Chris Lattner  for_each(M->gbegin(), M->gend(),
435c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner	   bind_obj(this, &AssemblyWriter::printGlobal));
436007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
4375efa3ccbd17e81358f87474e53492871b1c83e41Vikram S. Adve  Out << "implementation\n";
4385efa3ccbd17e81358f87474e53492871b1c83e41Vikram S. Adve
439b579400cd72f274607f4964a9649ea4d38e04c46Chris Lattner  // Output all of the functions...
44079df7c0aaa18129e55968c8783ef8346807bd4afChris Lattner  for_each(M->begin(), M->end(), bind_obj(this,&AssemblyWriter::printFunction));
441009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
442009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
443c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattnervoid AssemblyWriter::printGlobal(const GlobalVariable *GV) {
44470cc3397f84c2e1fd69c059a0ef89e398e847b00Chris Lattner  if (GV->hasName()) Out << "%" << GV->getName() << " = ";
445d70684f7585a85c4248c1c224059478108741c70Chris Lattner
446dda719665ba2ffd2eb1c32a0d2daa3921448db7cChris Lattner  if (GV->hasInternalLinkage()) Out << "internal ";
447d70684f7585a85c4248c1c224059478108741c70Chris Lattner  if (!GV->hasInitializer()) Out << "uninitialized ";
448d70684f7585a85c4248c1c224059478108741c70Chris Lattner
449c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  Out << (GV->isConstant() ? "constant " : "global ");
4507a1767520611d9ff6face702068de858e1cadf2cChris Lattner  printType(GV->getType()->getElementType());
451d70684f7585a85c4248c1c224059478108741c70Chris Lattner
452d70684f7585a85c4248c1c224059478108741c70Chris Lattner  if (GV->hasInitializer())
453d70684f7585a85c4248c1c224059478108741c70Chris Lattner    writeOperand(GV->getInitializer(), false, false);
454d70684f7585a85c4248c1c224059478108741c70Chris Lattner
455e02fa8551d20081534afa46e0976811687e5183aChris Lattner  printInfoComment(GV);
456697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  Out << "\n";
45770cc3397f84c2e1fd69c059a0ef89e398e847b00Chris Lattner}
45870cc3397f84c2e1fd69c059a0ef89e398e847b00Chris Lattner
459009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
460c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner// printSymbolTable - Run through symbol table looking for named constants
461007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner// if a named constant is found, emit it's declaration...
462007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner//
463c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattnervoid AssemblyWriter::printSymbolTable(const SymbolTable &ST) {
464007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  for (SymbolTable::const_iterator TI = ST.begin(); TI != ST.end(); ++TI) {
465007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    SymbolTable::type_const_iterator I = ST.type_begin(TI->first);
466007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    SymbolTable::type_const_iterator End = ST.type_end(TI->first);
467007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
468007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    for (; I != End; ++I) {
469007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner      const Value *V = I->second;
470e9bb2df410f7a22decad9a883f7139d5857c1520Chris Lattner      if (const Constant *CPV = dyn_cast<const Constant>(V)) {
471c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner	printConstant(CPV);
4721d87bcf4909b06dcd86320722653341f08b8b396Chris Lattner      } else if (const Type *Ty = dyn_cast<const Type>(V)) {
4732761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner	Out << "\t%" << I->first << " = type ";
4742761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner
4752761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner        // Make sure we print out at least one level of the type structure, so
4762761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner        // that we do not get %FILE = type %FILE
4772761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner        //
4782761e9f076bbe6c961629aece62db4b836a41ef8Chris Lattner        printTypeAtLeastOneLevel(Ty) << "\n";
479007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner      }
480007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    }
481739a56d26ddd76f7d073745d8be25c53cf39dce5Chris Lattner  }
482009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
483009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
484009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
485c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner// printConstant - Print out a constant pool entry...
486009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
487e9bb2df410f7a22decad9a883f7139d5857c1520Chris Lattnervoid AssemblyWriter::printConstant(const Constant *CPV) {
488007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  // Don't print out unnamed constants, they will be inlined
489007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  if (!CPV->hasName()) return;
490009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
4911333ed5b4fd3d30ba9ef56741af4d345a9e43953Chris Lattner  // Print out name...
4927a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner  Out << "\t%" << CPV->getName() << " =";
493009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
494009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Write the value out now...
4957a716addedc4938fa0ec6b77e5eeaced6eafc5d0Chris Lattner  writeOperand(CPV, true, false);
496009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
497009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (!CPV->hasName() && CPV->getType() != Type::VoidTy) {
498009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    int Slot = Table.getValSlot(CPV); // Print out the def slot taken...
499c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    Out << "\t\t; <";
500c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    printType(CPV->getType()) << ">:";
501009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    if (Slot >= 0) Out << Slot;
502009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    else Out << "<badref>";
503009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
504009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
505697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  Out << "\n";
506009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
507009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
508b579400cd72f274607f4964a9649ea4d38e04c46Chris Lattner// printFunction - Print all aspects of a function.
509009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
51079df7c0aaa18129e55968c8783ef8346807bd4afChris Lattnervoid AssemblyWriter::printFunction(const Function *M) {
511009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Print out the return type and name...
512dda719665ba2ffd2eb1c32a0d2daa3921448db7cChris Lattner  Out << "\n" << (M->isExternal() ? "declare " : "")
513dda719665ba2ffd2eb1c32a0d2daa3921448db7cChris Lattner      << (M->hasInternalLinkage() ? "internal " : "");
514c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  printType(M->getReturnType()) << " \"" << M->getName() << "\"(";
515b579400cd72f274607f4964a9649ea4d38e04c46Chris Lattner  Table.incorporateFunction(M);
516007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
517c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  // Loop over the arguments, printing them...
5186bfd6a578a3a4fa95c585c988ee712ba880f9923Chris Lattner  const FunctionType *MT = M->getFunctionType();
519007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
520e02fa8551d20081534afa46e0976811687e5183aChris Lattner  if (!M->isExternal()) {
521e02fa8551d20081534afa46e0976811687e5183aChris Lattner    for_each(M->getArgumentList().begin(), M->getArgumentList().end(),
52273e214244f2403b5ba0ef81b8839600f3c8ffebcChris Lattner	     bind_obj(this, &AssemblyWriter::printArgument));
523e02fa8551d20081534afa46e0976811687e5183aChris Lattner  } else {
524c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    // Loop over the arguments, printing them...
5256bfd6a578a3a4fa95c585c988ee712ba880f9923Chris Lattner    const FunctionType *MT = M->getFunctionType();
5266bfd6a578a3a4fa95c585c988ee712ba880f9923Chris Lattner    for (FunctionType::ParamTypes::const_iterator I = MT->getParamTypes().begin(),
527e02fa8551d20081534afa46e0976811687e5183aChris Lattner	   E = MT->getParamTypes().end(); I != E; ++I) {
528e02fa8551d20081534afa46e0976811687e5183aChris Lattner      if (I != MT->getParamTypes().begin()) Out << ", ";
529c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner      printType(*I);
530e02fa8551d20081534afa46e0976811687e5183aChris Lattner    }
531e02fa8551d20081534afa46e0976811687e5183aChris Lattner  }
532007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
533007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  // Finish printing arguments...
534007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  if (MT->isVarArg()) {
535007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    if (MT->getParamTypes().size()) Out << ", ";
536007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    Out << "...";  // Output varargs portion of signature!
537007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  }
538007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  Out << ")\n";
539007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
540007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  if (!M->isExternal()) {
541007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    // Loop over the symbol table, emitting all named constants...
542007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    if (M->hasSymbolTable())
543c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner      printSymbolTable(*M->getSymbolTable());
544007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
545007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    Out << "begin";
546007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
547b579400cd72f274607f4964a9649ea4d38e04c46Chris Lattner    // Output all of its basic blocks... for the function
548007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    for_each(M->begin(), M->end(),
549c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner	     bind_obj(this, &AssemblyWriter::printBasicBlock));
550007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
551739a56d26ddd76f7d073745d8be25c53cf39dce5Chris Lattner    Out << "end\n";
552007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  }
553007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
554b579400cd72f274607f4964a9649ea4d38e04c46Chris Lattner  Table.purgeFunction();
555009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
556009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
55773e214244f2403b5ba0ef81b8839600f3c8ffebcChris Lattner// printArgument - This member is called for every argument that
558b579400cd72f274607f4964a9649ea4d38e04c46Chris Lattner// is passed into the function.  Simply print it out
559009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
56073e214244f2403b5ba0ef81b8839600f3c8ffebcChris Lattnervoid AssemblyWriter::printArgument(const Argument *Arg) {
561009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Insert commas as we go... the first arg doesn't get a comma
562009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (Arg != Arg->getParent()->getArgumentList().front()) Out << ", ";
563009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
564009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Output type...
565c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner  printType(Arg->getType());
566009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
567009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Output name, if available...
568009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (Arg->hasName())
569009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << " %" << Arg->getName();
570009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  else if (Table.getValSlot(Arg) < 0)
571009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << "<badref>";
572009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
573009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
574c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner// printBasicBlock - This member is called for each basic block in a methd.
575009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
576c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattnervoid AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
577009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (BB->hasName()) {              // Print out the label if it exists...
578b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner    Out << "\n" << BB->getName() << ":";
579009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  } else {
580009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    int Slot = Table.getValSlot(BB);
581b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner    Out << "\n; <label>:";
582009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    if (Slot >= 0)
583b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner      Out << Slot;         // Extra newline seperates out label's
584009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    else
585b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner      Out << "<badref>";
586009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
587b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner  Out << "\t\t\t\t\t;[#uses=" << BB->use_size() << "]\n";  // Output # uses
588009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
589007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  // Output all of the instructions in the basic block...
590007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  for_each(BB->begin(), BB->end(),
591c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner	   bind_obj(this, &AssemblyWriter::printInstruction));
592009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
593009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
594e02fa8551d20081534afa46e0976811687e5183aChris Lattner
595e02fa8551d20081534afa46e0976811687e5183aChris Lattner// printInfoComment - Print a little comment after the instruction indicating
596e02fa8551d20081534afa46e0976811687e5183aChris Lattner// which slot it occupies.
597e02fa8551d20081534afa46e0976811687e5183aChris Lattner//
598e02fa8551d20081534afa46e0976811687e5183aChris Lattnervoid AssemblyWriter::printInfoComment(const Value *V) {
599e02fa8551d20081534afa46e0976811687e5183aChris Lattner  if (V->getType() != Type::VoidTy) {
600c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    Out << "\t\t; <";
601c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    printType(V->getType()) << ">";
602e02fa8551d20081534afa46e0976811687e5183aChris Lattner
603e02fa8551d20081534afa46e0976811687e5183aChris Lattner    if (!V->hasName()) {
604e02fa8551d20081534afa46e0976811687e5183aChris Lattner      int Slot = Table.getValSlot(V); // Print out the def slot taken...
605e02fa8551d20081534afa46e0976811687e5183aChris Lattner      if (Slot >= 0) Out << ":" << Slot;
606e02fa8551d20081534afa46e0976811687e5183aChris Lattner      else Out << ":<badref>";
607e02fa8551d20081534afa46e0976811687e5183aChris Lattner    }
608f7a551fd929a4a849883cde04cfe54e0590a38b7Chris Lattner    Out << " [#uses=" << V->use_size() << "]";  // Output # uses
609e02fa8551d20081534afa46e0976811687e5183aChris Lattner  }
610e02fa8551d20081534afa46e0976811687e5183aChris Lattner}
611e02fa8551d20081534afa46e0976811687e5183aChris Lattner
612c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner// printInstruction - This member is called for each Instruction in a methd.
613009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
614c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattnervoid AssemblyWriter::printInstruction(const Instruction *I) {
615009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  Out << "\t";
616009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
617009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Print out name if it exists...
618009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (I && I->hasName())
619009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << "%" << I->getName() << " = ";
620009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
621009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Print out the opcode...
622a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner  Out << I->getOpcodeName();
623009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
624009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Print out the type of the operands...
625c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner  const Value *Operand = I->getNumOperands() ? I->getOperand(0) : 0;
626009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
627009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Special case conditional branches to swizzle the condition out to the front
62894dc1f29cd1dc669680b7d3caa1f59862a656b83Chris Lattner  if (isa<BranchInst>(I) && I->getNumOperands() > 1) {
629009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    writeOperand(I->getOperand(2), true);
630009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << ",";
631009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    writeOperand(Operand, true);
632009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << ",";
633009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    writeOperand(I->getOperand(1), true);
634009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
63594dc1f29cd1dc669680b7d3caa1f59862a656b83Chris Lattner  } else if (isa<SwitchInst>(I)) {
636009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    // Special case switch statement to get formatting nice and correct...
637009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    writeOperand(Operand         , true); Out << ",";
638009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    writeOperand(I->getOperand(1), true); Out << " [";
639009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
640c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) {
641009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      Out << "\n\t\t";
642c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      writeOperand(I->getOperand(op  ), true); Out << ",";
643009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      writeOperand(I->getOperand(op+1), true);
644009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    }
645009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << "\n\t]";
646b00c582b6d40e6b9ff2d1ed4f5eaf7930e792aceChris Lattner  } else if (isa<PHINode>(I)) {
647c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    Out << " ";
6488f410cac044a21a94afece41345ccd9b72047675Chris Lattner    printType(I->getType());
649eed1fc79735c3ade3dddc0d45eec2c9811969e21Chris Lattner    Out << " ";
650009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
6518f410cac044a21a94afece41345ccd9b72047675Chris Lattner    for (unsigned op = 0, Eop = I->getNumOperands(); op < Eop; op += 2) {
6528f410cac044a21a94afece41345ccd9b72047675Chris Lattner      if (op) Out << ", ";
6538f410cac044a21a94afece41345ccd9b72047675Chris Lattner      Out << "[";
654c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      writeOperand(I->getOperand(op  ), false); Out << ",";
65528d480b31623371e9d738d17a62dd0bd6cdce1cdChris Lattner      writeOperand(I->getOperand(op+1), false); Out << " ]";
656c24d2088dc3d79e3b7e38a358b4a71f156c06836Chris Lattner    }
657e02fa8551d20081534afa46e0976811687e5183aChris Lattner  } else if (isa<ReturnInst>(I) && !Operand) {
658009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << " void";
659e02fa8551d20081534afa46e0976811687e5183aChris Lattner  } else if (isa<CallInst>(I)) {
660268de0464ee9f0938bfa145fdd5e7f1a46b21cf7Chris Lattner    const PointerType *PTy = dyn_cast<PointerType>(Operand->getType());
6616bfd6a578a3a4fa95c585c988ee712ba880f9923Chris Lattner    const FunctionType*MTy = PTy ? dyn_cast<FunctionType>(PTy->getElementType()):0;
662268de0464ee9f0938bfa145fdd5e7f1a46b21cf7Chris Lattner    const Type      *RetTy = MTy ? MTy->getReturnType() : 0;
663268de0464ee9f0938bfa145fdd5e7f1a46b21cf7Chris Lattner
664268de0464ee9f0938bfa145fdd5e7f1a46b21cf7Chris Lattner    // If possible, print out the short form of the call instruction, but we can
665b579400cd72f274607f4964a9649ea4d38e04c46Chris Lattner    // only do this if the first argument is a pointer to a nonvararg function,
666b579400cd72f274607f4964a9649ea4d38e04c46Chris Lattner    // and if the value returned is not a pointer to a function.
667268de0464ee9f0938bfa145fdd5e7f1a46b21cf7Chris Lattner    //
66894dc1f29cd1dc669680b7d3caa1f59862a656b83Chris Lattner    if (RetTy && MTy && !MTy->isVarArg() &&
66994dc1f29cd1dc669680b7d3caa1f59862a656b83Chris Lattner        (!isa<PointerType>(RetTy) ||
67094dc1f29cd1dc669680b7d3caa1f59862a656b83Chris Lattner         !isa<FunctionType>(cast<PointerType>(RetTy)))) {
671268de0464ee9f0938bfa145fdd5e7f1a46b21cf7Chris Lattner      Out << " "; printType(RetTy);
672268de0464ee9f0938bfa145fdd5e7f1a46b21cf7Chris Lattner      writeOperand(Operand, false);
673268de0464ee9f0938bfa145fdd5e7f1a46b21cf7Chris Lattner    } else {
674268de0464ee9f0938bfa145fdd5e7f1a46b21cf7Chris Lattner      writeOperand(Operand, true);
675268de0464ee9f0938bfa145fdd5e7f1a46b21cf7Chris Lattner    }
676009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << "(";
677c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    if (I->getNumOperands() > 1) writeOperand(I->getOperand(1), true);
678c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; ++op) {
679009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      Out << ",";
680c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      writeOperand(I->getOperand(op), true);
681009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    }
682009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
683009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << " )";
684e02fa8551d20081534afa46e0976811687e5183aChris Lattner  } else if (const InvokeInst *II = dyn_cast<InvokeInst>(I)) {
685e02fa8551d20081534afa46e0976811687e5183aChris Lattner    // TODO: Should try to print out short form of the Invoke instruction
686e02fa8551d20081534afa46e0976811687e5183aChris Lattner    writeOperand(Operand, true);
687e02fa8551d20081534afa46e0976811687e5183aChris Lattner    Out << "(";
688e02fa8551d20081534afa46e0976811687e5183aChris Lattner    if (I->getNumOperands() > 3) writeOperand(I->getOperand(3), true);
689e02fa8551d20081534afa46e0976811687e5183aChris Lattner    for (unsigned op = 4, Eop = I->getNumOperands(); op < Eop; ++op) {
690e02fa8551d20081534afa46e0976811687e5183aChris Lattner      Out << ",";
691e02fa8551d20081534afa46e0976811687e5183aChris Lattner      writeOperand(I->getOperand(op), true);
692e02fa8551d20081534afa46e0976811687e5183aChris Lattner    }
693e02fa8551d20081534afa46e0976811687e5183aChris Lattner
694e02fa8551d20081534afa46e0976811687e5183aChris Lattner    Out << " )\n\t\t\tto";
695e02fa8551d20081534afa46e0976811687e5183aChris Lattner    writeOperand(II->getNormalDest(), true);
696e02fa8551d20081534afa46e0976811687e5183aChris Lattner    Out << " except";
697e02fa8551d20081534afa46e0976811687e5183aChris Lattner    writeOperand(II->getExceptionalDest(), true);
698e02fa8551d20081534afa46e0976811687e5183aChris Lattner
69994dc1f29cd1dc669680b7d3caa1f59862a656b83Chris Lattner  } else if (const AllocationInst *AI = dyn_cast<AllocationInst>(I)) {
700c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    Out << " ";
70194dc1f29cd1dc669680b7d3caa1f59862a656b83Chris Lattner    printType(AI->getType()->getElementType());
70294dc1f29cd1dc669680b7d3caa1f59862a656b83Chris Lattner    if (AI->isArrayAllocation()) {
703c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      Out << ",";
70494dc1f29cd1dc669680b7d3caa1f59862a656b83Chris Lattner      writeOperand(AI->getArraySize(), true);
705009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    }
706e02fa8551d20081534afa46e0976811687e5183aChris Lattner  } else if (isa<CastInst>(I)) {
7070908309e3c4b4f423e88d8d8fe8060cb10eaa1c9Chris Lattner    writeOperand(Operand, true);
708c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    Out << " to ";
709c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    printType(I->getType());
710009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  } else if (Operand) {   // Print the normal way...
711009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
712009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    // PrintAllTypes - Instructions who have operands of all the same type
713009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    // omit the type from all but the first operand.  If the instruction has
714009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    // different type operands (for example br), then they are all printed.
715009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    bool PrintAllTypes = false;
716009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    const Type *TheType = Operand->getType();
717009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
718c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    for (unsigned i = 1, E = I->getNumOperands(); i != E; ++i) {
719c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      Operand = I->getOperand(i);
720009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      if (Operand->getType() != TheType) {
721009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner	PrintAllTypes = true;       // We have differing types!  Print them all!
722009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner	break;
723009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      }
724009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    }
725009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
726f434cd1b30a77afa26de46a3e7afb8a07b536c6fChris Lattner    // Shift Left & Right print both types even for Ubyte LHS
727f434cd1b30a77afa26de46a3e7afb8a07b536c6fChris Lattner    if (isa<ShiftInst>(I)) PrintAllTypes = true;
728f434cd1b30a77afa26de46a3e7afb8a07b536c6fChris Lattner
729c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    if (!PrintAllTypes) {
730c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner      Out << " ";
731c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner      printType(I->getOperand(0)->getType());
732c1824996451d5ea93864fcd34ba8ea5e5f03e368Chris Lattner    }
733009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
734c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    for (unsigned i = 0, E = I->getNumOperands(); i != E; ++i) {
735009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      if (i) Out << ",";
736c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      writeOperand(I->getOperand(i), PrintAllTypes);
737009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    }
738009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
739009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
740e02fa8551d20081534afa46e0976811687e5183aChris Lattner  printInfoComment(I);
741697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  Out << "\n";
742009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
743009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
744009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
745009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===//
746009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//                       External Interface declarations
747009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===//
748009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
749009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
75075cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattnervoid Module::print(std::ostream &o) const {
75175cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  SlotCalculator SlotTable(this, true);
75275cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  AssemblyWriter W(o, SlotTable, this);
75375cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  W.write(this);
754009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
755009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
75675cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattnervoid GlobalVariable::print(std::ostream &o) const {
75775cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  SlotCalculator SlotTable(getParent(), true);
75875cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  AssemblyWriter W(o, SlotTable, getParent());
75975cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  W.write(this);
760b0e4523624fbe493a945ea73a8f3c6d6526f3f27Chris Lattner}
761b0e4523624fbe493a945ea73a8f3c6d6526f3f27Chris Lattner
76275cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattnervoid Function::print(std::ostream &o) const {
76375cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  SlotCalculator SlotTable(getParent(), true);
76475cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  AssemblyWriter W(o, SlotTable, getParent());
765009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
76675cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  W.write(this);
767009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
768009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
76975cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattnervoid BasicBlock::print(std::ostream &o) const {
77075cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  SlotCalculator SlotTable(getParent(), true);
77175cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  AssemblyWriter W(o, SlotTable,
77275cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner                   getParent() ? getParent()->getParent() : 0);
77375cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  W.write(this);
77475cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner}
775009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
77675cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattnervoid Instruction::print(std::ostream &o) const {
77775cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  const Function *F = getParent() ? getParent()->getParent() : 0;
77875cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  SlotCalculator SlotTable(F, true);
77975cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  AssemblyWriter W(o, SlotTable, F ? F->getParent() : 0);
780009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
78175cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  W.write(this);
78275cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner}
783009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
78475cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattnervoid Constant::print(std::ostream &o) const {
78575cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  if (this == 0) { o << "<null> constant value\n"; return; }
78675cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  o << " " << getType()->getDescription() << " " << getStrValue();
787009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
788009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
78975cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattnervoid Type::print(std::ostream &o) const {
79075cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  if (this == 0)
79175cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner    o << "<null Type>";
79275cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  else
79375cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner    o << getDescription();
794009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
795009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
79673e214244f2403b5ba0ef81b8839600f3c8ffebcChris Lattnervoid Argument::print(std::ostream &o) const {
79775cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner  o << getType() << " " << getName();
79875cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner}
799009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
80075cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattnervoid Value::dump() const { print(std::cerr); }
801009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
80275cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner//===----------------------------------------------------------------------===//
80375cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner//  CachedWriter Class Implementation
80475cf7cf00d391ac6ca22d6240fa9d99ed427d1d5Chris Lattner//===----------------------------------------------------------------------===//
805da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner
806da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattnervoid CachedWriter::setModule(const Module *M) {
807da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner  delete SC; delete AW;
808da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner  if (M) {
809da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner    SC = new SlotCalculator(M, true);
810da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner    AW = new AssemblyWriter(Out, *SC, M);
811da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner  } else {
812da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner    SC = 0; AW = 0;
813da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner  }
814da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner}
815da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner
816da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris LattnerCachedWriter::~CachedWriter() {
817da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner  delete AW;
818da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner  delete SC;
819da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner}
820da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner
821da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris LattnerCachedWriter &CachedWriter::operator<<(const Value *V) {
822da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner  assert(AW && SC && "CachedWriter does not have a current module!");
823da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner  switch (V->getValueType()) {
824da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner  case Value::ConstantVal:
825da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner    Out << " "; AW->write(V->getType());
826e9bb2df410f7a22decad9a883f7139d5857c1520Chris Lattner    Out << " " << cast<Constant>(V)->getStrValue(); break;
82773e214244f2403b5ba0ef81b8839600f3c8ffebcChris Lattner  case Value::ArgumentVal:
828da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner    AW->write(V->getType()); Out << " " << V->getName(); break;
829da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner  case Value::TypeVal:           AW->write(cast<const Type>(V)); break;
830da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner  case Value::InstructionVal:    AW->write(cast<Instruction>(V)); break;
831da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner  case Value::BasicBlockVal:     AW->write(cast<BasicBlock>(V)); break;
83279df7c0aaa18129e55968c8783ef8346807bd4afChris Lattner  case Value::FunctionVal:       AW->write(cast<Function>(V)); break;
833da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner  case Value::GlobalVariableVal: AW->write(cast<GlobalVariable>(V)); break;
834da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner  case Value::ModuleVal:         AW->write(cast<Module>(V)); break;
835da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner  default: Out << "<unknown value type: " << V->getValueType() << ">"; break;
836da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner  }
837da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner  return *this;
838da1fbcc5c389e86840f6131afc22b45ce7e9ad08Chris Lattner}
839