add option for literal formatting to APInt::toString()

toString() now takes an optional bool argument that,
depending on the radix, adds the appropriate prefix
to the integer's string representation that makes it into a
meaningful C literal, e.g.:

hexademical: '-f' becomes '-0xf'
octal: '77' becomes '077'
binary: '110' becomes '0b110'

Patch by nobled@dreamwidth.org!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133032 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ted Kremenek 2011-06-15 00:51:55 +00:00
parent a990e071f2
commit cf886188fb
2 changed files with 38 additions and 6 deletions

View File

@ -1241,18 +1241,19 @@ public:
/// toString - Converts an APInt to a string and append it to Str. Str is
/// commonly a SmallString.
void toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed) const;
void toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
bool formatAsCLiteral = false) const;
/// Considers the APInt to be unsigned and converts it into a string in the
/// radix given. The radix can be 2, 8, 10 or 16.
void toStringUnsigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
toString(Str, Radix, false);
toString(Str, Radix, false, false);
}
/// Considers the APInt to be signed and converts it into a string in the
/// radix given. The radix can be 2, 8, 10 or 16.
void toStringSigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
toString(Str, Radix, true);
toString(Str, Radix, true, false);
}
/// toString - This returns the APInt as a std::string. Note that this is an

View File

@ -2164,12 +2164,33 @@ void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) {
}
void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix,
bool Signed) const {
bool Signed, bool formatAsCLiteral) const {
assert((Radix == 10 || Radix == 8 || Radix == 16 || Radix == 2) &&
"Radix should be 2, 8, 10, or 16!");
const char *Prefix = "";
if (formatAsCLiteral) {
switch (Radix) {
case 2:
// Binary literals are a non-standard extension added in gcc 4.3:
// http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Binary-constants.html
Prefix = "0b";
break;
case 8:
Prefix = "0";
break;
case 16:
Prefix = "0x";
break;
}
}
// First, check for a zero value and just short circuit the logic below.
if (*this == 0) {
while (*Prefix) {
Str.push_back(*Prefix);
++Prefix;
};
Str.push_back('0');
return;
}
@ -2193,6 +2214,11 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix,
}
}
while (*Prefix) {
Str.push_back(*Prefix);
++Prefix;
};
while (N) {
*--BufPtr = Digits[N % Radix];
N /= Radix;
@ -2212,6 +2238,11 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix,
Str.push_back('-');
}
while (*Prefix) {
Str.push_back(*Prefix);
++Prefix;
};
// We insert the digits backward, then reverse them to get the right order.
unsigned StartDig = Str.size();
@ -2251,7 +2282,7 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix,
/// to the methods above.
std::string APInt::toString(unsigned Radix = 10, bool Signed = true) const {
SmallString<40> S;
toString(S, Radix, Signed);
toString(S, Radix, Signed, /* formatAsCLiteral = */false);
return S.str();
}
@ -2266,7 +2297,7 @@ void APInt::dump() const {
void APInt::print(raw_ostream &OS, bool isSigned) const {
SmallString<40> S;
this->toString(S, 10, isSigned);
this->toString(S, 10, isSigned, /* formatAsCLiteral = */false);
OS << S.str();
}