Changes to:
* Fix bug printing method types (oops when converting previous code)
* Move some of the code from Constant::getStrValue implementations here.
This allows us to do a MUCH MUCH better job printing out complex constant
values (think an array of structure pointers), because we print symbolic
type names instead of structural. The assistance when debugging is immense
Eventually, Constant::getStrValue should be removed (it existed before because
the asmwriter file was not in VMCore), and everyone should go through the
asmwriter that want's equivalent functionality.
llvm-svn: 2268
diff --git a/llvm/lib/VMCore/AsmWriter.cpp b/llvm/lib/VMCore/AsmWriter.cpp
index 2e5f75d..97dcf45 100644
--- a/llvm/lib/VMCore/AsmWriter.cpp
+++ b/llvm/lib/VMCore/AsmWriter.cpp
@@ -34,6 +34,10 @@
using std::vector;
using std::ostream;
+static void WriteAsOperandInternal(ostream &Out, const Value *V, bool PrintName,
+ map<const Type *, string> &TypeTable,
+ SlotCalculator *Table);
+
static const Module *getModuleFromVal(const Value *V) {
if (const Argument *MA = dyn_cast<const Argument>(V))
return MA->getParent() ? MA->getParent()->getParent() : 0;
@@ -67,40 +71,6 @@
return 0;
}
-// WriteAsOperand - Write the name of the specified value out to the specified
-// ostream. This can be useful when you just want to print int %reg126, not the
-// whole instruction that generated it.
-//
-static void WriteAsOperandInternal(ostream &Out, const Value *V, bool PrintName,
- SlotCalculator *Table) {
- if (PrintName && V->hasName()) {
- Out << " %" << V->getName();
- } else {
- if (const Constant *CPV = dyn_cast<const Constant>(V)) {
- Out << " " << CPV->getStrValue();
- } else {
- int Slot;
- if (Table) {
- Slot = Table->getValSlot(V);
- } else {
- if (const Type *Ty = dyn_cast<const Type>(V)) {
- Out << " " << Ty->getDescription();
- return;
- }
-
- Table = createSlotCalculator(V);
- if (Table == 0) { Out << "BAD VALUE TYPE!"; return; }
-
- Slot = Table->getValSlot(V);
- delete Table;
- }
- if (Slot >= 0) Out << " %" << Slot;
- else if (PrintName)
- Out << "<badref>"; // Not embeded into a location?
- }
- }
-}
-
// If the module has a symbol table, take all global types and stuff their
// names into the TypeNames map.
@@ -244,6 +214,95 @@
}
}
+static void WriteConstantInt(ostream &Out, const Constant *CV, bool PrintName,
+ map<const Type *, string> &TypeTable,
+ SlotCalculator *Table) {
+ if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
+ const Type *SubType = CA->getType()->getElementType();
+ if (SubType == Type::SByteTy) {
+ Out << CV->getStrValue(); // Output string format if possible...
+ } else {
+ Out << "[";
+ if (CA->getNumOperands()) {
+ Out << " ";
+ printTypeInt(Out, SubType, TypeTable);
+ WriteAsOperandInternal(Out, CA->getOperand(0),
+ PrintName, TypeTable, Table);
+ for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
+ Out << ", ";
+ printTypeInt(Out, SubType, TypeTable);
+ WriteAsOperandInternal(Out, CA->getOperand(i), PrintName,
+ TypeTable, Table);
+ }
+ }
+ Out << " ]";
+ }
+ } else if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
+ Out << "{";
+ if (CS->getNumOperands()) {
+ Out << " ";
+ printTypeInt(Out, CS->getOperand(0)->getType(), TypeTable);
+
+ WriteAsOperandInternal(Out, CS->getOperand(0),
+ PrintName, TypeTable, Table);
+
+ for (unsigned i = 1; i < CS->getNumOperands(); i++) {
+ Out << ", ";
+ printTypeInt(Out, CS->getOperand(i)->getType(), TypeTable);
+
+ WriteAsOperandInternal(Out, CS->getOperand(i),
+ PrintName, TypeTable, Table);
+ }
+ }
+
+ Out << " }";
+ } else if (isa<ConstantPointerNull>(CV)) {
+ Out << "null";
+
+ // FIXME: Handle ConstantPointerRef + lots of others...
+ } else {
+ Out << CV->getStrValue();
+ }
+}
+
+
+// WriteAsOperand - Write the name of the specified value out to the specified
+// ostream. This can be useful when you just want to print int %reg126, not the
+// whole instruction that generated it.
+//
+static void WriteAsOperandInternal(ostream &Out, const Value *V, bool PrintName,
+ map<const Type *, string> &TypeTable,
+ SlotCalculator *Table) {
+ Out << " ";
+ if (PrintName && V->hasName()) {
+ Out << "%" << V->getName();
+ } else {
+ if (const Constant *CV = dyn_cast<const Constant>(V)) {
+ WriteConstantInt(Out, CV, PrintName, TypeTable, Table);
+ } else {
+ int Slot;
+ if (Table) {
+ Slot = Table->getValSlot(V);
+ } else {
+ if (const Type *Ty = dyn_cast<const Type>(V)) {
+ Out << Ty->getDescription();
+ return;
+ }
+
+ Table = createSlotCalculator(V);
+ if (Table == 0) { Out << "BAD VALUE TYPE!"; return; }
+
+ Slot = Table->getValSlot(V);
+ delete Table;
+ }
+ if (Slot >= 0) Out << "%" << Slot;
+ else if (PrintName)
+ Out << "<badref>"; // Not embeded into a location?
+ }
+ }
+}
+
+
// WriteAsOperand - Write the name of the specified value out to the specified
// ostream. This can be useful when you just want to print int %reg126, not the
@@ -251,10 +310,16 @@
//
ostream &WriteAsOperand(ostream &Out, const Value *V, bool PrintType,
bool PrintName, SlotCalculator *Table) {
- if (PrintType)
- WriteTypeSymbolic(Out, V->getType(), getModuleFromVal(V));
+ map<const Type *, string> TypeNames;
+ const Module *M = getModuleFromVal(V);
- WriteAsOperandInternal(Out, V, PrintName, Table);
+ if (M && M->hasSymbolTable())
+ fillTypeNameTable(M, TypeNames);
+
+ if (PrintType)
+ printTypeInt(Out, V->getType(), TypeNames);
+
+ WriteAsOperandInternal(Out, V, PrintName, TypeNames, Table);
return Out;
}
@@ -324,7 +389,7 @@
E = FTy->getParamTypes().end(); I != E; ++I) {
if (I != FTy->getParamTypes().begin())
Out << ", ";
- Out << printType(*I);
+ printType(*I);
}
if (FTy->isVarArg()) {
if (!FTy->getParamTypes().empty()) Out << ", ";
@@ -357,7 +422,7 @@
void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType,
bool PrintName) {
if (PrintType) { Out << " "; printType(Operand->getType()); }
- WriteAsOperandInternal(Out, Operand, PrintName, &Table);
+ WriteAsOperandInternal(Out, Operand, PrintName, TypeNames, &Table);
}
@@ -424,13 +489,10 @@
if (!CPV->hasName()) return;
// Print out name...
- Out << "\t%" << CPV->getName() << " = ";
-
- // Print out the constant type...
- printType(CPV->getType());
+ Out << "\t%" << CPV->getName() << " =";
// Write the value out now...
- writeOperand(CPV, false, false);
+ writeOperand(CPV, true, false);
if (!CPV->hasName() && CPV->getType() != Type::VoidTy) {
int Slot = Table.getValSlot(CPV); // Print out the def slot taken...