class AssemblyWriter:

* Make contained ostream pointer, not reference
* Allow setting of that ostream via setStream()

class CachedWriter:
* setStream() in turn calls setStream() on the AssemblyWriter

llvm-svn: 13247
This commit is contained in:
Misha Brukman 2004-04-28 19:24:28 +00:00
parent 2dc1944f14
commit da546eac70
1 changed files with 109 additions and 103 deletions

View File

@ -449,7 +449,7 @@ std::ostream &llvm::WriteAsOperand(std::ostream &Out, const Value *V,
namespace llvm { namespace llvm {
class AssemblyWriter { class AssemblyWriter {
std::ostream &Out; std::ostream *Out;
SlotCalculator &Table; SlotCalculator &Table;
const Module *TheModule; const Module *TheModule;
std::map<const Type *, std::string> TypeNames; std::map<const Type *, std::string> TypeNames;
@ -457,7 +457,7 @@ class AssemblyWriter {
public: public:
inline AssemblyWriter(std::ostream &o, SlotCalculator &Tab, const Module *M, inline AssemblyWriter(std::ostream &o, SlotCalculator &Tab, const Module *M,
AssemblyAnnotationWriter *AAW) AssemblyAnnotationWriter *AAW)
: Out(o), Table(Tab), TheModule(M), AnnotationWriter(AAW) { : Out(&o), Table(Tab), TheModule(M), AnnotationWriter(AAW) {
// If the module has a symbol table, take all global types and stuff their // If the module has a symbol table, take all global types and stuff their
// names into the TypeNames map. // names into the TypeNames map.
@ -476,6 +476,7 @@ public:
void writeOperand(const Value *Op, bool PrintType, bool PrintName = true); void writeOperand(const Value *Op, bool PrintType, bool PrintName = true);
const Module* getModule() { return TheModule; } const Module* getModule() { return TheModule; }
void setStream(std::ostream &os) { Out = &os; }
private : private :
void printModule(const Module *M); void printModule(const Module *M);
@ -491,7 +492,7 @@ private :
// symbolic version of a type name. // symbolic version of a type name.
// //
std::ostream &printType(const Type *Ty) { std::ostream &printType(const Type *Ty) {
return printTypeInt(Out, Ty, TypeNames); return printTypeInt(*Out, Ty, TypeNames);
} }
// printTypeAtLeastOneLevel - Print out one level of the possibly complex type // printTypeAtLeastOneLevel - Print out one level of the possibly complex type
@ -514,55 +515,55 @@ std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) {
for (FunctionType::param_iterator I = FTy->param_begin(), for (FunctionType::param_iterator I = FTy->param_begin(),
E = FTy->param_end(); I != E; ++I) { E = FTy->param_end(); I != E; ++I) {
if (I != FTy->param_begin()) if (I != FTy->param_begin())
Out << ", "; *Out << ", ";
printType(*I); printType(*I);
} }
if (FTy->isVarArg()) { if (FTy->isVarArg()) {
if (FTy->getNumParams()) Out << ", "; if (FTy->getNumParams()) *Out << ", ";
Out << "..."; *Out << "...";
} }
Out << ")"; *Out << ")";
} else if (const StructType *STy = dyn_cast<StructType>(Ty)) { } else if (const StructType *STy = dyn_cast<StructType>(Ty)) {
Out << "{ "; *Out << "{ ";
for (StructType::element_iterator I = STy->element_begin(), for (StructType::element_iterator I = STy->element_begin(),
E = STy->element_end(); I != E; ++I) { E = STy->element_end(); I != E; ++I) {
if (I != STy->element_begin()) if (I != STy->element_begin())
Out << ", "; *Out << ", ";
printType(*I); printType(*I);
} }
Out << " }"; *Out << " }";
} else if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) { } else if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
printType(PTy->getElementType()) << "*"; printType(PTy->getElementType()) << "*";
} else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) { } else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
Out << "[" << ATy->getNumElements() << " x "; *Out << "[" << ATy->getNumElements() << " x ";
printType(ATy->getElementType()) << "]"; printType(ATy->getElementType()) << "]";
} else if (const OpaqueType *OTy = dyn_cast<OpaqueType>(Ty)) { } else if (const OpaqueType *OTy = dyn_cast<OpaqueType>(Ty)) {
Out << "opaque"; *Out << "opaque";
} else { } else {
if (!Ty->isPrimitiveType()) if (!Ty->isPrimitiveType())
Out << "<unknown derived type>"; *Out << "<unknown derived type>";
printType(Ty); printType(Ty);
} }
return Out; return *Out;
} }
void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType, void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType,
bool PrintName) { bool PrintName) {
if (PrintType) { Out << " "; printType(Operand->getType()); } if (PrintType) { *Out << " "; printType(Operand->getType()); }
WriteAsOperandInternal(Out, Operand, PrintName, TypeNames, &Table); WriteAsOperandInternal(*Out, Operand, PrintName, TypeNames, &Table);
} }
void AssemblyWriter::printModule(const Module *M) { void AssemblyWriter::printModule(const Module *M) {
switch (M->getEndianness()) { switch (M->getEndianness()) {
case Module::LittleEndian: Out << "target endian = little\n"; break; case Module::LittleEndian: *Out << "target endian = little\n"; break;
case Module::BigEndian: Out << "target endian = big\n"; break; case Module::BigEndian: *Out << "target endian = big\n"; break;
case Module::AnyEndianness: break; case Module::AnyEndianness: break;
} }
switch (M->getPointerSize()) { switch (M->getPointerSize()) {
case Module::Pointer32: Out << "target pointersize = 32\n"; break; case Module::Pointer32: *Out << "target pointersize = 32\n"; break;
case Module::Pointer64: Out << "target pointersize = 64\n"; break; case Module::Pointer64: *Out << "target pointersize = 64\n"; break;
case Module::AnyPointerSize: break; case Module::AnyPointerSize: break;
} }
@ -572,7 +573,7 @@ void AssemblyWriter::printModule(const Module *M) {
for (Module::const_giterator I = M->gbegin(), E = M->gend(); I != E; ++I) for (Module::const_giterator I = M->gbegin(), E = M->gend(); I != E; ++I)
printGlobal(I); printGlobal(I);
Out << "\nimplementation ; Functions:\n"; *Out << "\nimplementation ; Functions:\n";
// Output all of the functions... // Output all of the functions...
for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
@ -580,27 +581,27 @@ void AssemblyWriter::printModule(const Module *M) {
} }
void AssemblyWriter::printGlobal(const GlobalVariable *GV) { void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
if (GV->hasName()) Out << getLLVMName(GV->getName()) << " = "; if (GV->hasName()) *Out << getLLVMName(GV->getName()) << " = ";
if (!GV->hasInitializer()) if (!GV->hasInitializer())
Out << "external "; *Out << "external ";
else else
switch (GV->getLinkage()) { switch (GV->getLinkage()) {
case GlobalValue::InternalLinkage: Out << "internal "; break; case GlobalValue::InternalLinkage: *Out << "internal "; break;
case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break; case GlobalValue::LinkOnceLinkage: *Out << "linkonce "; break;
case GlobalValue::WeakLinkage: Out << "weak "; break; case GlobalValue::WeakLinkage: *Out << "weak "; break;
case GlobalValue::AppendingLinkage: Out << "appending "; break; case GlobalValue::AppendingLinkage: *Out << "appending "; break;
case GlobalValue::ExternalLinkage: break; case GlobalValue::ExternalLinkage: break;
} }
Out << (GV->isConstant() ? "constant " : "global "); *Out << (GV->isConstant() ? "constant " : "global ");
printType(GV->getType()->getElementType()); printType(GV->getType()->getElementType());
if (GV->hasInitializer()) if (GV->hasInitializer())
writeOperand(GV->getInitializer(), false, false); writeOperand(GV->getInitializer(), false, false);
printInfoComment(*GV); printInfoComment(*GV);
Out << "\n"; *Out << "\n";
} }
@ -618,7 +619,7 @@ void AssemblyWriter::printSymbolTable(const SymbolTable &ST) {
printConstant(CPV); printConstant(CPV);
} else if (const Type *Ty = dyn_cast<Type>(V)) { } else if (const Type *Ty = dyn_cast<Type>(V)) {
assert(Ty->getType() == Type::TypeTy && TI->first == Type::TypeTy); assert(Ty->getType() == Type::TypeTy && TI->first == Type::TypeTy);
Out << "\t" << getLLVMName(I->first) << " = type "; *Out << "\t" << getLLVMName(I->first) << " = type ";
// Make sure we print out at least one level of the type structure, so // Make sure we print out at least one level of the type structure, so
// that we do not get %FILE = type %FILE // that we do not get %FILE = type %FILE
@ -637,40 +638,40 @@ void AssemblyWriter::printConstant(const Constant *CPV) {
if (!CPV->hasName()) return; if (!CPV->hasName()) return;
// Print out name... // Print out name...
Out << "\t" << getLLVMName(CPV->getName()) << " ="; *Out << "\t" << getLLVMName(CPV->getName()) << " =";
// Write the value out now... // Write the value out now...
writeOperand(CPV, true, false); writeOperand(CPV, true, false);
printInfoComment(*CPV); printInfoComment(*CPV);
Out << "\n"; *Out << "\n";
} }
/// printFunction - Print all aspects of a function. /// printFunction - Print all aspects of a function.
/// ///
void AssemblyWriter::printFunction(const Function *F) { void AssemblyWriter::printFunction(const Function *F) {
// Print out the return type and name... // Print out the return type and name...
Out << "\n"; *Out << "\n";
if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out); if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, *Out);
if (F->isExternal()) if (F->isExternal())
Out << "declare "; *Out << "declare ";
else else
switch (F->getLinkage()) { switch (F->getLinkage()) {
case GlobalValue::InternalLinkage: Out << "internal "; break; case GlobalValue::InternalLinkage: *Out << "internal "; break;
case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break; case GlobalValue::LinkOnceLinkage: *Out << "linkonce "; break;
case GlobalValue::WeakLinkage: Out << "weak "; break; case GlobalValue::WeakLinkage: *Out << "weak "; break;
case GlobalValue::AppendingLinkage: Out << "appending "; break; case GlobalValue::AppendingLinkage: *Out << "appending "; break;
case GlobalValue::ExternalLinkage: break; case GlobalValue::ExternalLinkage: break;
} }
printType(F->getReturnType()) << " "; printType(F->getReturnType()) << " ";
if (!F->getName().empty()) if (!F->getName().empty())
Out << getLLVMName(F->getName()); *Out << getLLVMName(F->getName());
else else
Out << "\"\""; *Out << "\"\"";
Out << "("; *Out << "(";
Table.incorporateFunction(F); Table.incorporateFunction(F);
// Loop over the arguments, printing them... // Loop over the arguments, printing them...
@ -681,21 +682,21 @@ void AssemblyWriter::printFunction(const Function *F) {
// Finish printing arguments... // Finish printing arguments...
if (FT->isVarArg()) { if (FT->isVarArg()) {
if (FT->getNumParams()) Out << ", "; if (FT->getNumParams()) *Out << ", ";
Out << "..."; // Output varargs portion of signature! *Out << "..."; // Output varargs portion of signature!
} }
Out << ")"; *Out << ")";
if (F->isExternal()) { if (F->isExternal()) {
Out << "\n"; *Out << "\n";
} else { } else {
Out << " {"; *Out << " {";
// Output all of its basic blocks... for the function // Output all of its basic blocks... for the function
for (Function::const_iterator I = F->begin(), E = F->end(); I != E; ++I) for (Function::const_iterator I = F->begin(), E = F->end(); I != E; ++I)
printBasicBlock(I); printBasicBlock(I);
Out << "}\n"; *Out << "}\n";
} }
Table.purgeFunction(); Table.purgeFunction();
@ -706,62 +707,62 @@ void AssemblyWriter::printFunction(const Function *F) {
/// ///
void AssemblyWriter::printArgument(const Argument *Arg) { void AssemblyWriter::printArgument(const Argument *Arg) {
// Insert commas as we go... the first arg doesn't get a comma // Insert commas as we go... the first arg doesn't get a comma
if (Arg != &Arg->getParent()->afront()) Out << ", "; if (Arg != &Arg->getParent()->afront()) *Out << ", ";
// Output type... // Output type...
printType(Arg->getType()); printType(Arg->getType());
// Output name, if available... // Output name, if available...
if (Arg->hasName()) if (Arg->hasName())
Out << " " << getLLVMName(Arg->getName()); *Out << " " << getLLVMName(Arg->getName());
else if (Table.getSlot(Arg) < 0) else if (Table.getSlot(Arg) < 0)
Out << "<badref>"; *Out << "<badref>";
} }
/// printBasicBlock - This member is called for each basic block in a method. /// printBasicBlock - This member is called for each basic block in a method.
/// ///
void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
if (BB->hasName()) { // Print out the label if it exists... if (BB->hasName()) { // Print out the label if it exists...
Out << "\n" << BB->getName() << ":"; *Out << "\n" << BB->getName() << ":";
} else if (!BB->use_empty()) { // Don't print block # of no uses... } else if (!BB->use_empty()) { // Don't print block # of no uses...
int Slot = Table.getSlot(BB); int Slot = Table.getSlot(BB);
Out << "\n; <label>:"; *Out << "\n; <label>:";
if (Slot >= 0) if (Slot >= 0)
Out << Slot; // Extra newline separates out label's *Out << Slot; // Extra newline separates out label's
else else
Out << "<badref>"; *Out << "<badref>";
} }
if (BB->getParent() == 0) if (BB->getParent() == 0)
Out << "\t\t; Error: Block without parent!"; *Out << "\t\t; Error: Block without parent!";
else { else {
if (BB != &BB->getParent()->front()) { // Not the entry block? if (BB != &BB->getParent()->front()) { // Not the entry block?
// Output predecessors for the block... // Output predecessors for the block...
Out << "\t\t;"; *Out << "\t\t;";
pred_const_iterator PI = pred_begin(BB), PE = pred_end(BB); pred_const_iterator PI = pred_begin(BB), PE = pred_end(BB);
if (PI == PE) { if (PI == PE) {
Out << " No predecessors!"; *Out << " No predecessors!";
} else { } else {
Out << " preds ="; *Out << " preds =";
writeOperand(*PI, false, true); writeOperand(*PI, false, true);
for (++PI; PI != PE; ++PI) { for (++PI; PI != PE; ++PI) {
Out << ","; *Out << ",";
writeOperand(*PI, false, true); writeOperand(*PI, false, true);
} }
} }
} }
} }
Out << "\n"; *Out << "\n";
if (AnnotationWriter) AnnotationWriter->emitBasicBlockStartAnnot(BB, Out); if (AnnotationWriter) AnnotationWriter->emitBasicBlockStartAnnot(BB, *Out);
// Output all of the instructions in the basic block... // Output all of the instructions in the basic block...
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
printInstruction(*I); printInstruction(*I);
if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out); if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, *Out);
} }
@ -770,36 +771,36 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
/// ///
void AssemblyWriter::printInfoComment(const Value &V) { void AssemblyWriter::printInfoComment(const Value &V) {
if (V.getType() != Type::VoidTy) { if (V.getType() != Type::VoidTy) {
Out << "\t\t; <"; *Out << "\t\t; <";
printType(V.getType()) << ">"; printType(V.getType()) << ">";
if (!V.hasName()) { if (!V.hasName()) {
int Slot = Table.getSlot(&V); // Print out the def slot taken... int Slot = Table.getSlot(&V); // Print out the def slot taken...
if (Slot >= 0) Out << ":" << Slot; if (Slot >= 0) *Out << ":" << Slot;
else Out << ":<badref>"; else *Out << ":<badref>";
} }
Out << " [#uses=" << V.use_size() << "]"; // Output # uses *Out << " [#uses=" << V.use_size() << "]"; // Output # uses
} }
} }
/// printInstruction - This member is called for each Instruction in a method. /// printInstruction - This member is called for each Instruction in a method.
/// ///
void AssemblyWriter::printInstruction(const Instruction &I) { void AssemblyWriter::printInstruction(const Instruction &I) {
if (AnnotationWriter) AnnotationWriter->emitInstructionAnnot(&I, Out); if (AnnotationWriter) AnnotationWriter->emitInstructionAnnot(&I, *Out);
Out << "\t"; *Out << "\t";
// Print out name if it exists... // Print out name if it exists...
if (I.hasName()) if (I.hasName())
Out << getLLVMName(I.getName()) << " = "; *Out << getLLVMName(I.getName()) << " = ";
// If this is a volatile load or store, print out the volatile marker // If this is a volatile load or store, print out the volatile marker
if ((isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) || if ((isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) ||
(isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile())) (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile()))
Out << "volatile "; *Out << "volatile ";
// Print out the opcode... // Print out the opcode...
Out << I.getOpcodeName(); *Out << I.getOpcodeName();
// Print out the type of the operands... // Print out the type of the operands...
const Value *Operand = I.getNumOperands() ? I.getOperand(0) : 0; const Value *Operand = I.getNumOperands() ? I.getOperand(0) : 0;
@ -807,35 +808,35 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
// Special case conditional branches to swizzle the condition out to the front // Special case conditional branches to swizzle the condition out to the front
if (isa<BranchInst>(I) && I.getNumOperands() > 1) { if (isa<BranchInst>(I) && I.getNumOperands() > 1) {
writeOperand(I.getOperand(2), true); writeOperand(I.getOperand(2), true);
Out << ","; *Out << ",";
writeOperand(Operand, true); writeOperand(Operand, true);
Out << ","; *Out << ",";
writeOperand(I.getOperand(1), true); writeOperand(I.getOperand(1), true);
} else if (isa<SwitchInst>(I)) { } else if (isa<SwitchInst>(I)) {
// Special case switch statement to get formatting nice and correct... // Special case switch statement to get formatting nice and correct...
writeOperand(Operand , true); Out << ","; writeOperand(Operand , true); *Out << ",";
writeOperand(I.getOperand(1), true); Out << " ["; writeOperand(I.getOperand(1), true); *Out << " [";
for (unsigned op = 2, Eop = I.getNumOperands(); op < Eop; op += 2) { for (unsigned op = 2, Eop = I.getNumOperands(); op < Eop; op += 2) {
Out << "\n\t\t"; *Out << "\n\t\t";
writeOperand(I.getOperand(op ), true); Out << ","; writeOperand(I.getOperand(op ), true); *Out << ",";
writeOperand(I.getOperand(op+1), true); writeOperand(I.getOperand(op+1), true);
} }
Out << "\n\t]"; *Out << "\n\t]";
} else if (isa<PHINode>(I)) { } else if (isa<PHINode>(I)) {
Out << " "; *Out << " ";
printType(I.getType()); printType(I.getType());
Out << " "; *Out << " ";
for (unsigned op = 0, Eop = I.getNumOperands(); op < Eop; op += 2) { for (unsigned op = 0, Eop = I.getNumOperands(); op < Eop; op += 2) {
if (op) Out << ", "; if (op) *Out << ", ";
Out << "["; *Out << "[";
writeOperand(I.getOperand(op ), false); Out << ","; writeOperand(I.getOperand(op ), false); *Out << ",";
writeOperand(I.getOperand(op+1), false); Out << " ]"; writeOperand(I.getOperand(op+1), false); *Out << " ]";
} }
} else if (isa<ReturnInst>(I) && !Operand) { } else if (isa<ReturnInst>(I) && !Operand) {
Out << " void"; *Out << " void";
} else if (isa<CallInst>(I)) { } else if (isa<CallInst>(I)) {
const PointerType *PTy = cast<PointerType>(Operand->getType()); const PointerType *PTy = cast<PointerType>(Operand->getType());
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
@ -848,19 +849,19 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
if (!FTy->isVarArg() && if (!FTy->isVarArg() &&
(!isa<PointerType>(RetTy) || (!isa<PointerType>(RetTy) ||
!isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) { !isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) {
Out << " "; printType(RetTy); *Out << " "; printType(RetTy);
writeOperand(Operand, false); writeOperand(Operand, false);
} else { } else {
writeOperand(Operand, true); writeOperand(Operand, true);
} }
Out << "("; *Out << "(";
if (I.getNumOperands() > 1) writeOperand(I.getOperand(1), true); if (I.getNumOperands() > 1) writeOperand(I.getOperand(1), true);
for (unsigned op = 2, Eop = I.getNumOperands(); op < Eop; ++op) { for (unsigned op = 2, Eop = I.getNumOperands(); op < Eop; ++op) {
Out << ","; *Out << ",";
writeOperand(I.getOperand(op), true); writeOperand(I.getOperand(op), true);
} }
Out << " )"; *Out << " )";
} else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) { } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
const PointerType *PTy = cast<PointerType>(Operand->getType()); const PointerType *PTy = cast<PointerType>(Operand->getType());
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
@ -873,42 +874,42 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
if (!FTy->isVarArg() && if (!FTy->isVarArg() &&
(!isa<PointerType>(RetTy) || (!isa<PointerType>(RetTy) ||
!isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) { !isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) {
Out << " "; printType(RetTy); *Out << " "; printType(RetTy);
writeOperand(Operand, false); writeOperand(Operand, false);
} else { } else {
writeOperand(Operand, true); writeOperand(Operand, true);
} }
Out << "("; *Out << "(";
if (I.getNumOperands() > 3) writeOperand(I.getOperand(3), true); if (I.getNumOperands() > 3) writeOperand(I.getOperand(3), true);
for (unsigned op = 4, Eop = I.getNumOperands(); op < Eop; ++op) { for (unsigned op = 4, Eop = I.getNumOperands(); op < Eop; ++op) {
Out << ","; *Out << ",";
writeOperand(I.getOperand(op), true); writeOperand(I.getOperand(op), true);
} }
Out << " )\n\t\t\tto"; *Out << " )\n\t\t\tto";
writeOperand(II->getNormalDest(), true); writeOperand(II->getNormalDest(), true);
Out << " unwind"; *Out << " unwind";
writeOperand(II->getUnwindDest(), true); writeOperand(II->getUnwindDest(), true);
} else if (const AllocationInst *AI = dyn_cast<AllocationInst>(&I)) { } else if (const AllocationInst *AI = dyn_cast<AllocationInst>(&I)) {
Out << " "; *Out << " ";
printType(AI->getType()->getElementType()); printType(AI->getType()->getElementType());
if (AI->isArrayAllocation()) { if (AI->isArrayAllocation()) {
Out << ","; *Out << ",";
writeOperand(AI->getArraySize(), true); writeOperand(AI->getArraySize(), true);
} }
} else if (isa<CastInst>(I)) { } else if (isa<CastInst>(I)) {
if (Operand) writeOperand(Operand, true); // Work with broken code if (Operand) writeOperand(Operand, true); // Work with broken code
Out << " to "; *Out << " to ";
printType(I.getType()); printType(I.getType());
} else if (isa<VAArgInst>(I)) { } else if (isa<VAArgInst>(I)) {
if (Operand) writeOperand(Operand, true); // Work with broken code if (Operand) writeOperand(Operand, true); // Work with broken code
Out << ", "; *Out << ", ";
printType(I.getType()); printType(I.getType());
} else if (const VANextInst *VAN = dyn_cast<VANextInst>(&I)) { } else if (const VANextInst *VAN = dyn_cast<VANextInst>(&I)) {
if (Operand) writeOperand(Operand, true); // Work with broken code if (Operand) writeOperand(Operand, true); // Work with broken code
Out << ", "; *Out << ", ";
printType(VAN->getArgType()); printType(VAN->getArgType());
} else if (Operand) { // Print the normal way... } else if (Operand) { // Print the normal way...
@ -933,18 +934,18 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
} }
if (!PrintAllTypes) { if (!PrintAllTypes) {
Out << " "; *Out << " ";
printType(TheType); printType(TheType);
} }
for (unsigned i = 0, E = I.getNumOperands(); i != E; ++i) { for (unsigned i = 0, E = I.getNumOperands(); i != E; ++i) {
if (i) Out << ","; if (i) *Out << ",";
writeOperand(I.getOperand(i), PrintAllTypes); writeOperand(I.getOperand(i), PrintAllTypes);
} }
} }
printInfoComment(I); printInfoComment(I);
Out << "\n"; *Out << "\n";
} }
@ -1056,3 +1057,8 @@ CachedWriter& CachedWriter::operator<<(const Type *X) {
} else } else
return *this << (const Value*)X; return *this << (const Value*)X;
} }
void CachedWriter::setStream(std::ostream &os) {
Out = &os;
if (AW) AW->setStream(os);
}