From 02da6c0f08913a793b3cbc01d8e11932bf51ec29 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 16 Jun 2003 12:09:09 +0000 Subject: [PATCH] Fix bug: CBackend/2003-06-11-HexConstant.ll Fix bug: CBackend/2003-06-11-LiteralStringProblem.ll git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6697 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/CBackend/CBackend.cpp | 22 +++++++++++++++++----- lib/Target/CBackend/Writer.cpp | 22 +++++++++++++++++----- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 39e09fb40f3..9915b5951da 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -285,24 +285,35 @@ void CWriter::printConstantArray(ConstantArray *CPA) { bool isString = (ETy == Type::SByteTy || ETy == Type::UByteTy); // Make sure the last character is a null char, as automatically added by C - if (CPA->getNumOperands() == 0 || - !cast(*(CPA->op_end()-1))->isNullValue()) + if (isString && (CPA->getNumOperands() == 0 || + !cast(*(CPA->op_end()-1))->isNullValue())) isString = false; if (isString) { Out << "\""; + // Keep track of whether the last number was a hexadecimal escape + bool LastWasHex = false; + // Do not include the last character, which we know is null for (unsigned i = 0, e = CPA->getNumOperands()-1; i != e; ++i) { unsigned char C = (ETy == Type::SByteTy) ? (unsigned char)cast(CPA->getOperand(i))->getValue() : (unsigned char)cast(CPA->getOperand(i))->getValue(); - if (isprint(C)) { + // Print it out literally if it is a printable character. The only thing + // to be careful about is when the last letter output was a hex escape + // code, in which case we have to be careful not to print out hex digits + // explicitly (the C compiler things it is a continuation of the previous + // character, arg...) + // + if (isprint(C) && (!LastWasHex || !isxdigit(C))) { + LastWasHex = false; if (C == '"' || C == '\\') Out << "\\" << C; else Out << C; } else { + LastWasHex = false; switch (C) { case '\n': Out << "\\n"; break; case '\t': Out << "\\t"; break; @@ -313,8 +324,9 @@ void CWriter::printConstantArray(ConstantArray *CPA) { case '\'': Out << "\\\'"; break; default: Out << "\\x"; - Out << ( C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A'); - Out << ((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'); + Out << (char)(( C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A')); + Out << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A')); + LastWasHex = true; break; } } diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp index 39e09fb40f3..9915b5951da 100644 --- a/lib/Target/CBackend/Writer.cpp +++ b/lib/Target/CBackend/Writer.cpp @@ -285,24 +285,35 @@ void CWriter::printConstantArray(ConstantArray *CPA) { bool isString = (ETy == Type::SByteTy || ETy == Type::UByteTy); // Make sure the last character is a null char, as automatically added by C - if (CPA->getNumOperands() == 0 || - !cast(*(CPA->op_end()-1))->isNullValue()) + if (isString && (CPA->getNumOperands() == 0 || + !cast(*(CPA->op_end()-1))->isNullValue())) isString = false; if (isString) { Out << "\""; + // Keep track of whether the last number was a hexadecimal escape + bool LastWasHex = false; + // Do not include the last character, which we know is null for (unsigned i = 0, e = CPA->getNumOperands()-1; i != e; ++i) { unsigned char C = (ETy == Type::SByteTy) ? (unsigned char)cast(CPA->getOperand(i))->getValue() : (unsigned char)cast(CPA->getOperand(i))->getValue(); - if (isprint(C)) { + // Print it out literally if it is a printable character. The only thing + // to be careful about is when the last letter output was a hex escape + // code, in which case we have to be careful not to print out hex digits + // explicitly (the C compiler things it is a continuation of the previous + // character, arg...) + // + if (isprint(C) && (!LastWasHex || !isxdigit(C))) { + LastWasHex = false; if (C == '"' || C == '\\') Out << "\\" << C; else Out << C; } else { + LastWasHex = false; switch (C) { case '\n': Out << "\\n"; break; case '\t': Out << "\\t"; break; @@ -313,8 +324,9 @@ void CWriter::printConstantArray(ConstantArray *CPA) { case '\'': Out << "\\\'"; break; default: Out << "\\x"; - Out << ( C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A'); - Out << ((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'); + Out << (char)(( C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A')); + Out << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A')); + LastWasHex = true; break; } }