From 66e810be9f97fa744ca949d54b5d54358add84b8 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 18 Apr 2002 18:53:13 +0000 Subject: [PATCH] Pull all of the getStrValue implementation cruft out of Constants.cpp and 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 | 118 +++++++++++++++++++++++++++++++-------- 1 file changed, 94 insertions(+), 24 deletions(-) diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 97dcf45c3cc..41c139f9552 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/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 &TypeTable, SlotCalculator *Table) { - if (const ConstantArray *CA = dyn_cast(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(CV)) { + Out << (CB == ConstantBool::True ? "true" : "false"); + } else if (const ConstantSInt *CI = dyn_cast(CV)) { + Out << CI->getValue(); + } else if (const ConstantUInt *CI = dyn_cast(CV)) { + Out << CI->getValue(); + } else if (const ConstantFP *CFP = dyn_cast(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(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(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(CA->getOperand(i))->getValue() : + (unsigned char)cast(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(CV)) { Out << "null"; - // FIXME: Handle ConstantPointerRef + lots of others... + } else if (ConstantPointerRef *PR = dyn_cast(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 << ""; + } else { + Out << ""; + } } 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 << ""; - } - + 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 << " constant value\n"; return; } - o << " " << getType()->getDescription() << " " << getStrValue(); + o << " " << getType()->getDescription() << " "; + + map 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(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(V)); break; case Value::InstructionVal: AW->write(cast(V)); break; case Value::BasicBlockVal: AW->write(cast(V)); break; -- 2.34.1