diff options
Diffstat (limited to 'llvm/lib/VMCore/AsmWriter.cpp')
| -rw-r--r-- | llvm/lib/VMCore/AsmWriter.cpp | 118 | 
1 files changed, 94 insertions, 24 deletions
| diff --git a/llvm/lib/VMCore/AsmWriter.cpp b/llvm/lib/VMCore/AsmWriter.cpp index 97dcf45c3cc..41c139f9552 100644 --- a/llvm/lib/VMCore/AsmWriter.cpp +++ b/llvm/lib/VMCore/AsmWriter.cpp @@ -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; | 

