llvm.org GIT mirror llvm / 1b2f643
with recent changes, ConstantArray is never a "string". Remove the associated methods and constant fold the clients to false. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149362 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 8 years ago
8 changed file(s) with 51 addition(s) and 262 deletion(s). Raw diff Collapse all Expand all
371371 inline ArrayType *getType() const {
372372 return reinterpret_cast(Value::getType());
373373 }
374
375 // FIXME: String methods will eventually be removed.
376
377
378 /// isString - This method returns true if the array is an array of i8 and
379 /// the elements of the array are all ConstantInt's.
380 bool isString() const;
381
382 /// isCString - This method returns true if the array is a string (see
383 /// @verbatim
384 /// isString) and it ends in a null byte \0 and does not contains any other
385 /// @endverbatim
386 /// null bytes except its terminator.
387 bool isCString() const;
388
389 /// getAsString - If this array is isString(), then this method converts the
390 /// array to an std::string and returns it. Otherwise, it asserts out.
391 ///
392 std::string getAsString() const;
393
394 /// getAsCString - If this array is isCString(), then this method converts the
395 /// array (without the trailing null byte) to an std::string and returns it.
396 /// Otherwise, it asserts out.
397 ///
398 std::string getAsCString() const;
399374
400375 virtual void destroyConstant();
401376 virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
844844 } else {
845845 assert (0 && "Unknown FP type!");
846846 }
847 } else if (isa(C) && cast(C)->isString()) {
848 const ConstantArray *CA = cast(C);
849 // Emit constant strings specially.
850 unsigned NumOps = CA->getNumOperands();
851 // If this is a null-terminated string, use the denser CSTRING encoding.
852 if (CA->getOperand(NumOps-1)->isNullValue()) {
853 Code = bitc::CST_CODE_CSTRING;
854 --NumOps; // Don't encode the null, which isn't allowed by char6.
855 } else {
856 Code = bitc::CST_CODE_STRING;
857 AbbrevToUse = String8Abbrev;
858 }
859 bool isCStr7 = Code == bitc::CST_CODE_CSTRING;
860 bool isCStrChar6 = Code == bitc::CST_CODE_CSTRING;
861 for (unsigned i = 0; i != NumOps; ++i) {
862 unsigned char V = cast(CA->getOperand(i))->getZExtValue();
863 Record.push_back(V);
864 isCStr7 &= (V & 128) == 0;
865 if (isCStrChar6)
866 isCStrChar6 = BitCodeAbbrevOp::isChar6(V);
867 }
868
869 if (isCStrChar6)
870 AbbrevToUse = CString6Abbrev;
871 else if (isCStr7)
872 AbbrevToUse = CString7Abbrev;
873847 } else if (isa(C) &&
874848 cast(C)->isString()) {
875849 const ConstantDataSequential *Str = cast(C);
320320 if (const Constant *C = dyn_cast(V)) {
321321 if (isa(C)) {
322322 // Initializers for globals are handled explicitly elsewhere.
323 } else if (isa(C) && cast(C)->isString()) {
324 // Do not enumerate the initializers for an array of simple characters.
325 // The initializers just pollute the value table, and we emit the strings
326 // specially.
327323 } else if (C->getNumOperands()) {
328324 // If a constant has operands, enumerate them. This makes sure that if a
329325 // constant has uses (for example an array of const ints), that they are
16741674
16751675 static void EmitGlobalConstantArray(const ConstantArray *CA, unsigned AddrSpace,
16761676 AsmPrinter &AP) {
1677 if (AddrSpace != 0 || !CA->isString()) {
1678 // Not a string. Print the values in successive locations.
1679
1680 // See if we can aggregate some values. Make sure it can be
1681 // represented as a series of bytes of the constant value.
1682 int Value = isRepeatedByteSequence(CA, AP.TM);
1683
1684 if (Value != -1) {
1685 uint64_t Bytes = AP.TM.getTargetData()->getTypeAllocSize(CA->getType());
1686 AP.OutStreamer.EmitFill(Bytes, Value, AddrSpace);
1687 }
1688 else {
1689 for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
1690 EmitGlobalConstantImpl(CA->getOperand(i), AddrSpace, AP);
1691 }
1692 return;
1693 }
1694
1695 // Otherwise, it can be emitted as .ascii.
1696 SmallVector TmpVec;
1697 TmpVec.reserve(CA->getNumOperands());
1698 for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
1699 TmpVec.push_back(cast(CA->getOperand(i))->getZExtValue());
1700
1701 AP.OutStreamer.EmitBytes(StringRef(TmpVec.data(), TmpVec.size()), AddrSpace);
1677 // See if we can aggregate some values. Make sure it can be
1678 // represented as a series of bytes of the constant value.
1679 int Value = isRepeatedByteSequence(CA, AP.TM);
1680
1681 if (Value != -1) {
1682 uint64_t Bytes = AP.TM.getTargetData()->getTypeAllocSize(CA->getType());
1683 AP.OutStreamer.EmitFill(Bytes, Value, AddrSpace);
1684 }
1685 else {
1686 for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
1687 EmitGlobalConstantImpl(CA->getOperand(i), AddrSpace, AP);
1688 }
17021689 }
17031690
17041691 static void EmitGlobalConstantVector(const ConstantVector *CV,
557557 }
558558
559559 void CWriter::printConstantArray(ConstantArray *CPA, bool Static) {
560 // As a special case, print the array as a string if it is an array of
561 // ubytes or an array of sbytes with positive values.
562 //
563 if (CPA->isCString()) {
564 Out << '\"';
565 // Keep track of whether the last number was a hexadecimal escape.
566 bool LastWasHex = false;
567
568 // Do not include the last character, which we know is null
569 for (unsigned i = 0, e = CPA->getNumOperands()-1; i != e; ++i) {
570 unsigned char C = cast(CPA->getOperand(i))->getZExtValue();
571
572 // Print it out literally if it is a printable character. The only thing
573 // to be careful about is when the last letter output was a hex escape
574 // code, in which case we have to be careful not to print out hex digits
575 // explicitly (the C compiler thinks it is a continuation of the previous
576 // character, sheesh...)
577 //
578 if (isprint(C) && (!LastWasHex || !isxdigit(C))) {
579 LastWasHex = false;
580 if (C == '"' || C == '\\')
581 Out << "\\" << (char)C;
582 else
583 Out << (char)C;
584 } else {
585 LastWasHex = false;
586 switch (C) {
587 case '\n': Out << "\\n"; break;
588 case '\t': Out << "\\t"; break;
589 case '\r': Out << "\\r"; break;
590 case '\v': Out << "\\v"; break;
591 case '\a': Out << "\\a"; break;
592 case '\"': Out << "\\\""; break;
593 case '\'': Out << "\\\'"; break;
594 default:
595 Out << "\\x";
596 Out << (char)(( C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A'));
597 Out << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
598 LastWasHex = true;
599 break;
600 }
601 }
602 }
603 Out << '\"';
604 } else {
605 Out << '{';
606 if (CPA->getNumOperands()) {
607 Out << ' ';
608 printConstant(cast(CPA->getOperand(0)), Static);
609 for (unsigned i = 1, e = CPA->getNumOperands(); i != e; ++i) {
610 Out << ", ";
611 printConstant(cast(CPA->getOperand(i)), Static);
612 }
613 }
614 Out << " }";
615 }
560 Out << "{ ";
561 printConstant(cast(CPA->getOperand(0)), Static);
562 for (unsigned i = 1, e = CPA->getNumOperands(); i != e; ++i) {
563 Out << ", ";
564 printConstant(cast(CPA->getOperand(i)), Static);
565 }
566 Out << " }";
616567 }
617568
618569 void CWriter::printConstantVector(ConstantVector *CP, bool Static) {
619 Out << '{';
620 if (CP->getNumOperands()) {
621 Out << ' ';
622 printConstant(cast(CP->getOperand(0)), Static);
623 for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) {
624 Out << ", ";
625 printConstant(cast(CP->getOperand(i)), Static);
626 }
570 Out << "{ ";
571 printConstant(cast(CP->getOperand(0)), Static);
572 for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) {
573 Out << ", ";
574 printConstant(cast(CP->getOperand(i)), Static);
627575 }
628576 Out << " }";
629577 }
697697 printCFP(CFP);
698698 Out << ";";
699699 } else if (const ConstantArray *CA = dyn_cast(CV)) {
700 if (CA->isString()) {
701 Out << "Constant* " << constName <<
702 " = ConstantArray::get(mod->getContext(), \"";
703 std::string tmp = CA->getAsString();
704 bool nullTerminate = false;
705 if (tmp[tmp.length()-1] == 0) {
706 tmp.erase(tmp.length()-1);
707 nullTerminate = true;
708 }
709 printEscapedString(tmp);
710 // Determine if we want null termination or not.
711 if (nullTerminate)
712 Out << "\", true"; // Indicate that the null terminator should be
713 // added.
714 else
715 Out << "\", false";// No null terminator
716 Out << ");";
717 } else {
718 Out << "std::vector " << constName << "_elems;";
719 nl(Out);
720 unsigned N = CA->getNumOperands();
721 for (unsigned i = 0; i < N; ++i) {
722 printConstant(CA->getOperand(i)); // recurse to print operands
723 Out << constName << "_elems.push_back("
724 << getCppName(CA->getOperand(i)) << ");";
725 nl(Out);
726 }
727 Out << "Constant* " << constName << " = ConstantArray::get("
728 << typeName << ", " << constName << "_elems);";
729 }
700 Out << "std::vector " << constName << "_elems;";
701 nl(Out);
702 unsigned N = CA->getNumOperands();
703 for (unsigned i = 0; i < N; ++i) {
704 printConstant(CA->getOperand(i)); // recurse to print operands
705 Out << constName << "_elems.push_back("
706 << getCppName(CA->getOperand(i)) << ");";
707 nl(Out);
708 }
709 Out << "Constant* " << constName << " = ConstantArray::get("
710 << typeName << ", " << constName << "_elems);";
730711 } else if (const ConstantStruct *CS = dyn_cast(CV)) {
731712 Out << "std::vector " << constName << "_fields;";
732713 nl(Out);
739720 }
740721 Out << "Constant* " << constName << " = ConstantStruct::get("
741722 << typeName << ", " << constName << "_fields);";
742 } else if (const ConstantVector *CP = dyn_cast(CV)) {
723 } else if (const ConstantVector *CV = dyn_cast(CV)) {
743724 Out << "std::vector " << constName << "_elems;";
744725 nl(Out);
745 unsigned N = CP->getNumOperands();
726 unsigned N = CV->getNumOperands();
746727 for (unsigned i = 0; i < N; ++i) {
747 printConstant(CP->getOperand(i));
728 printConstant(CV->getOperand(i));
748729 Out << constName << "_elems.push_back("
749 << getCppName(CP->getOperand(i)) << ");";
730 << getCppName(CV->getOperand(i)) << ");";
750731 nl(Out);
751732 }
752733 Out << "Constant* " << constName << " = ConstantVector::get("
759740 if (CDS->isString()) {
760741 Out << "Constant *" << constName <<
761742 " = ConstantDataArray::getString(mod->getContext(), \"";
762 StringRef Str = CA->getAsString();
743 StringRef Str = CDS->getAsString();
763744 bool nullTerminate = false;
764745 if (Str.back() == 0) {
765746 Str = Str.drop_back();
826826 }
827827
828828 if (const ConstantArray *CA = dyn_cast(CV)) {
829 // As a special case, print the array as a string if it is an array of
830 // i8 with ConstantInt values.
831 //
832829 Type *ETy = CA->getType()->getElementType();
833 if (CA->isString()) {
834 Out << "c\"";
835 PrintEscapedString(CA->getAsString(), Out);
836 Out << '"';
837 } else { // Cannot output in string format...
838 Out << '[';
830 Out << '[';
831 TypePrinter.print(ETy, Out);
832 Out << ' ';
833 WriteAsOperandInternal(Out, CA->getOperand(0),
834 &TypePrinter, Machine,
835 Context);
836 for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
837 Out << ", ";
839838 TypePrinter.print(ETy, Out);
840839 Out << ' ';
841 WriteAsOperandInternal(Out, CA->getOperand(0),
842 &TypePrinter, Machine,
840 WriteAsOperandInternal(Out, CA->getOperand(i), &TypePrinter, Machine,
843841 Context);
844 for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
845 Out << ", ";
846 TypePrinter.print(ETy, Out);
847 Out << ' ';
848 WriteAsOperandInternal(Out, CA->getOperand(i), &TypePrinter, Machine,
849 Context);
850 }
851 Out << ']';
852 }
842 }
843 Out << ']';
853844 return;
854845 }
855846
12001200 destroyConstantImpl();
12011201 }
12021202
1203 /// isString - This method returns true if the array is an array of i8, and
1204 /// if the elements of the array are all ConstantInt's.
1205 bool ConstantArray::isString() const {
1206 // Check the element type for i8...
1207 if (!getType()->getElementType()->isIntegerTy(8))
1208 return false;
1209 // Check the elements to make sure they are all integers, not constant
1210 // expressions.
1211 for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
1212 if (!isa(getOperand(i)))
1213 return false;
1214 return true;
1215 }
1216
1217 /// isCString - This method returns true if the array is a string (see
1218 /// isString) and it ends in a null byte \\0 and does not contains any other
1219 /// null bytes except its terminator.
1220 bool ConstantArray::isCString() const {
1221 // Check the element type for i8...
1222 if (!getType()->getElementType()->isIntegerTy(8))
1223 return false;
1224
1225 // Last element must be a null.
1226 if (!getOperand(getNumOperands()-1)->isNullValue())
1227 return false;
1228 // Other elements must be non-null integers.
1229 for (unsigned i = 0, e = getNumOperands()-1; i != e; ++i) {
1230 if (!isa(getOperand(i)))
1231 return false;
1232 if (getOperand(i)->isNullValue())
1233 return false;
1234 }
1235 return true;
1236 }
1237
1238
1239 /// convertToString - Helper function for getAsString() and getAsCString().
1240 static std::string convertToString(const User *U, unsigned len) {
1241 std::string Result;
1242 Result.reserve(len);
1243 for (unsigned i = 0; i != len; ++i)
1244 Result.push_back((char)cast(U->getOperand(i))->getZExtValue());
1245 return Result;
1246 }
1247
1248 /// getAsString - If this array is isString(), then this method converts the
1249 /// array to an std::string and returns it. Otherwise, it asserts out.
1250 ///
1251 std::string ConstantArray::getAsString() const {
1252 assert(isString() && "Not a string!");
1253 return convertToString(this, getNumOperands());
1254 }
1255
1256
1257 /// getAsCString - If this array is isCString(), then this method converts the
1258 /// array (without the trailing null byte) to an std::string and returns it.
1259 /// Otherwise, it asserts out.
1260 ///
1261 std::string ConstantArray::getAsCString() const {
1262 assert(isCString() && "Not a string!");
1263 return convertToString(this, getNumOperands() - 1);
1264 }
1265
12661203
12671204 //---- ConstantStruct::get() implementation...
12681205 //