Skip to content

Commit

Permalink
add option for literal formatting to APInt::toString()
Browse files Browse the repository at this point in the history
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 [email protected]!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133032 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
tkremenek committed Jun 15, 2011
1 parent a990e07 commit cf88618
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 6 deletions.
7 changes: 4 additions & 3 deletions include/llvm/ADT/APInt.h
Original file line number Diff line number Diff line change
Expand Up @@ -1241,18 +1241,19 @@ class APInt {

/// 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
Expand Down
37 changes: 34 additions & 3 deletions lib/Support/APInt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
Expand All @@ -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();

Expand Down Expand Up @@ -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();
}

Expand All @@ -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();
}

Expand Down

0 comments on commit cf88618

Please sign in to comment.