Pull all of the getStrValue implementation cruft out of Constants.cpp and
authorChris Lattner <sabre@nondot.org>
Thu, 18 Apr 2002 18:53:13 +0000 (18:53 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 18 Apr 2002 18:53:13 +0000 (18:53 +0000)
put it into the AsmWriter.  This code is kinda gross and could probably be
cleaned up, but not now.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2299 91177308-0d34-0410-b5e6-96231b3b80d8

lib/VMCore/AsmWriter.cpp

index 97dcf45c3ccd901039726fbe88d05a4b5861a754..41c139f9552fcecbd83f4a06acb5e2bdd2fcede1 100644 (file)
@@ -217,20 +217,85 @@ ostream &WriteTypeSymbolic(ostream &Out, const Type *Ty, const Module *M) {
 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 {
+  if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) {
+    Out << (CB == ConstantBool::True ? "true" : "false");
+  } else if (const ConstantSInt *CI = dyn_cast<ConstantSInt>(CV)) {
+    Out << CI->getValue();
+  } else if (const ConstantUInt *CI = dyn_cast<ConstantUInt>(CV)) {
+    Out << CI->getValue();
+  } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
+    // We would like to output the FP constant value in exponential notation,
+    // but we cannot do this if doing so will lose precision.  Check here to
+    // make sure that we only output it in exponential format if we can parse
+    // the value back and get the same value.
+    //
+    std::string StrVal = ftostr(CFP->getValue());
+
+    // Check to make sure that the stringized number is not some string like
+    // "Inf" or NaN, that atof will accept, but the lexer will not.  Check that
+    // the string matches the "[-+]?[0-9]" regex.
+    //
+    if ((StrVal[0] >= '0' && StrVal[0] <= '9') ||
+        ((StrVal[0] == '-' || StrVal[0] == '+') &&
+         (StrVal[0] >= '0' && StrVal[0] <= '9')))
+      // Reparse stringized version!
+      if (atof(StrVal.c_str()) == CFP->getValue()) {
+        Out << StrVal; return;
+      }
+    
+    // Otherwise we could not reparse it to exactly the same value, so we must
+    // output the string in hexadecimal format!
+    //
+    // Behave nicely in the face of C TBAA rules... see:
+    // http://www.nullstone.com/htmls/category/aliastyp.htm
+    //
+    double Val = CFP->getValue();
+    char *Ptr = (char*)&Val;
+    assert(sizeof(double) == sizeof(uint64_t) && sizeof(double) == 8 &&
+           "assuming that double is 64 bits!");
+    Out << "0x" << utohexstr(*(uint64_t*)Ptr);
+
+  } else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
+    // As a special case, print the array as a string if it is an array of
+    // ubytes or an array of sbytes with positive values.
+    // 
+    const Type *ETy = CA->getType()->getElementType();
+    bool isString = (ETy == Type::SByteTy || ETy == Type::UByteTy);
+
+    if (ETy == Type::SByteTy)
+      for (unsigned i = 0; i < CA->getNumOperands(); ++i)
+        if (cast<ConstantSInt>(CA->getOperand(i))->getValue() < 0) {
+          isString = false;
+          break;
+        }
+
+    if (isString) {
+      Out << "c\"";
+      for (unsigned i = 0; i < CA->getNumOperands(); ++i) {
+        unsigned char C = (ETy == Type::SByteTy) ?
+          (unsigned char)cast<ConstantSInt>(CA->getOperand(i))->getValue() :
+          (unsigned char)cast<ConstantUInt>(CA->getOperand(i))->getValue();
+        
+        if (isprint(C)) {
+          Out << C;
+        } else {
+          Out << '\\'
+              << (char) ((C/16  < 10) ? ( C/16 +'0') : ( C/16 -10+'A'))
+              << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
+        }
+      }
+      Out << "\"";
+
+    } else {                // Cannot output in string format...
       Out << "[";
       if (CA->getNumOperands()) {
         Out << " ";
-        printTypeInt(Out, SubType, TypeTable);
+        printTypeInt(Out, ETy, TypeTable);
         WriteAsOperandInternal(Out, CA->getOperand(0),
                                PrintName, TypeTable, Table);
         for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
           Out << ", ";
-          printTypeInt(Out, SubType, TypeTable);
+          printTypeInt(Out, ETy, TypeTable);
           WriteAsOperandInternal(Out, CA->getOperand(i), PrintName,
                                  TypeTable, Table);
         }
@@ -259,9 +324,21 @@ static void WriteConstantInt(ostream &Out, const Constant *CV, bool PrintName,
   } else if (isa<ConstantPointerNull>(CV)) {
     Out << "null";
 
-    // FIXME: Handle ConstantPointerRef + lots of others...
+  } else if (ConstantPointerRef *PR = dyn_cast<ConstantPointerRef>(CV)) {
+    const GlobalValue *V = PR->getValue();
+    if (V->hasName()) {
+      Out << "%" << V->getName();
+    } else if (Table) {
+      int Slot = Table->getValSlot(V);
+      if (Slot >= 0)
+        Out << "%" << Slot;
+      else
+        Out << "<pointer reference badref>";
+    } else {
+      Out << "<pointer reference without context info>";
+    }
   } else {
-    Out << CV->getStrValue();
+    assert(0 && "Unrecognized constant value!!!");
   }
 }
 
@@ -348,6 +425,8 @@ public:
   inline void write(const Constant *CPV)     { printConstant(CPV);  }
   inline void write(const Type *Ty)          { printType(Ty);       }
 
+  void writeOperand(const Value *Op, bool PrintType, bool PrintName = true);
+
 private :
   void printModule(const Module *M);
   void printSymbolTable(const SymbolTable &ST);
@@ -370,8 +449,6 @@ private :
   //
   ostream &printTypeAtLeastOneLevel(const Type *Ty);
 
-  void writeOperand(const Value *Op, bool PrintType, bool PrintName = true);
-
   // printInfoComment - Print a little comment after the instruction indicating
   // which slot it occupies.
   void printInfoComment(const Value *V);
@@ -494,14 +571,7 @@ void AssemblyWriter::printConstant(const Constant *CPV) {
   // Write the value out now...
   writeOperand(CPV, true, false);
 
-  if (!CPV->hasName() && CPV->getType() != Type::VoidTy) {
-    int Slot = Table.getValSlot(CPV); // Print out the def slot taken...
-    Out << "\t\t; <";
-    printType(CPV->getType()) << ">:";
-    if (Slot >= 0) Out << Slot;
-    else Out << "<badref>";
-  } 
-
+  printInfoComment(CPV);
   Out << "\n";
 }
 
@@ -783,7 +853,10 @@ void Instruction::print(std::ostream &o) const {
 
 void Constant::print(std::ostream &o) const {
   if (this == 0) { o << "<null> constant value\n"; return; }
-  o << " " << getType()->getDescription() << " " << getStrValue();
+  o << " " << getType()->getDescription() << " ";
+
+  map<const Type *, string> TypeTable;
+  WriteConstantInt(o, this, false, TypeTable, 0);
 }
 
 void Type::print(std::ostream &o) const { 
@@ -822,10 +895,7 @@ CachedWriter &CachedWriter::operator<<(const Value *V) {
   assert(AW && SC && "CachedWriter does not have a current module!");
   switch (V->getValueType()) {
   case Value::ConstantVal:
-    Out << " "; AW->write(V->getType());
-    Out << " " << cast<Constant>(V)->getStrValue(); break;
-  case Value::ArgumentVal: 
-    AW->write(V->getType()); Out << " " << V->getName(); break;
+  case Value::ArgumentVal:       AW->writeOperand(V, true, true); break;
   case Value::TypeVal:           AW->write(cast<const Type>(V)); break;
   case Value::InstructionVal:    AW->write(cast<Instruction>(V)); break;
   case Value::BasicBlockVal:     AW->write(cast<BasicBlock>(V)); break;