summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ItaniumMangle.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2012-01-30 18:36:31 +0000
committerJohn McCall <rjmccall@apple.com>2012-01-30 18:36:31 +0000
commita023b6924a4c9cf4bb39af16be0556cbee099d52 (patch)
treec7fb82aa5ebd98665913f5bff742065d645698d6 /clang/lib/AST/ItaniumMangle.cpp
parentf06039b39d595d8eac14ee6412a10fd5c7ec93e1 (diff)
downloadbcm5719-llvm-a023b6924a4c9cf4bb39af16be0556cbee099d52.tar.gz
bcm5719-llvm-a023b6924a4c9cf4bb39af16be0556cbee099d52.zip
Per discussion on cxx-abi-dev, don't drop leading zeroes from the
mangling of floating-point literals. I just went ahead and reimplemented toString() here; if someone wants to generalize the library routine to do this, or feels strongly that we should be post-processing, please feel free. llvm-svn: 149256
Diffstat (limited to 'clang/lib/AST/ItaniumMangle.cpp')
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp42
1 files changed, 33 insertions, 9 deletions
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 427be32a460..fabf8cf0030 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -610,17 +610,41 @@ void CXXNameMangler::mangleFloat(const llvm::APFloat &f) {
// representation (IEEE on Itanium), high-order bytes first,
// without leading zeroes. For example: "Lf bf800000 E" is -1.0f
// on Itanium.
- // APInt::toString uses uppercase hexadecimal, and it's not really
- // worth embellishing that interface for this use case, so we just
- // do a second pass to lowercase things.
- typedef llvm::SmallString<20> buffer_t;
- buffer_t buffer;
- f.bitcastToAPInt().toString(buffer, 16, false);
+ // The 'without leading zeroes' thing seems to be an editorial
+ // mistake; see the discussion on cxx-abi-dev beginning on
+ // 2012-01-16.
- for (buffer_t::iterator i = buffer.begin(), e = buffer.end(); i != e; ++i)
- if (isupper(*i)) *i = tolower(*i);
+ // Our requirements here are just barely wierd enough to justify
+ // using a custom algorithm instead of post-processing APInt::toString().
- Out.write(buffer.data(), buffer.size());
+ llvm::APInt valueBits = f.bitcastToAPInt();
+ unsigned numCharacters = (valueBits.getBitWidth() + 3) / 4;
+ assert(numCharacters != 0);
+
+ // Allocate a buffer of the right number of characters.
+ llvm::SmallVector<char, 20> buffer;
+ buffer.set_size(numCharacters);
+
+ // Fill the buffer left-to-right.
+ for (unsigned stringIndex = 0; stringIndex != numCharacters; ++stringIndex) {
+ // The bit-index of the next hex digit.
+ unsigned digitBitIndex = 4 * (numCharacters - stringIndex - 1);
+
+ // Project out 4 bits starting at 'digitIndex'.
+ llvm::integerPart hexDigit
+ = valueBits.getRawData()[digitBitIndex / llvm::integerPartWidth];
+ hexDigit >>= (digitBitIndex % llvm::integerPartWidth);
+ hexDigit &= 0xF;
+
+ // Map that over to a lowercase hex digit.
+ static const char charForHex[16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+ };
+ buffer[stringIndex] = charForHex[hexDigit];
+ }
+
+ Out.write(buffer.data(), numCharacters);
}
void CXXNameMangler::mangleNumber(const llvm::APSInt &Value) {
OpenPOWER on IntegriCloud