diff options
author | David Majnemer <david.majnemer@gmail.com> | 2014-03-24 05:53:08 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2014-03-24 05:53:08 +0000 |
commit | 96bc4b03676655383766ca2337245a8d82f58403 (patch) | |
tree | 245207c6cac977543c4eb0b32f7a6783f56a0f18 /clang/lib | |
parent | 016d69d29feaa45f10c097e27a081cfa93fe0e2a (diff) | |
download | bcm5719-llvm-96bc4b03676655383766ca2337245a8d82f58403.tar.gz bcm5719-llvm-96bc4b03676655383766ca2337245a8d82f58403.zip |
MS ABI: Add tests, other cleanups for r204562
This commit cleans up a few accidents:
- Do not rely on the order in which StringLiteral lays out bytes.
- Use a more efficient mechanism for handling so-called
"special-mappings" when mangling string literals.
- There is no need to allocate a copy of the mangled name.
- Add the test written for r204562.
Thanks to Richard Smith for pointing these out!
llvm-svn: 204586
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 115 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 12 |
2 files changed, 64 insertions, 63 deletions
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index f5b9e23fa7a..9dfd2af8bb6 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -30,8 +30,6 @@ #include "llvm/ADT/StringMap.h" #include "llvm/Support/MathExtras.h" -#include <algorithm> - using namespace clang; namespace { @@ -2413,73 +2411,80 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL, // (including null-terminator bytes) of the StringLiteral. // Each character is encoded by splitting them into bytes and then encoding // the constituent bytes. - auto MangleCharacter = [&Mangler](char Byte) { + auto MangleByte = [&Mangler](char Byte) { // There are five different manglings for characters: - // - ?[0-9]: The set of [,/\:. \n\t'-]. // - [a-zA-Z0-9_$]: A one-to-one mapping. // - ?[a-z]: The range from \xe1 to \xfa. // - ?[A-Z]: The range from \xc1 to \xda. + // - ?[0-9]: The set of [,/\:. \n\t'-]. // - ?$XX: A fallback which maps nibbles. - static const char SpecialMap[] = {',', '/', '\\', ':', '.', - ' ', '\n', '\t', '\'', '-'}; - const char *SpecialMapI = - std::find(std::begin(SpecialMap), std::end(SpecialMap), Byte); - if (SpecialMapI != std::end(SpecialMap)) { - Mangler.getStream() << '?' << SpecialMapI - SpecialMap; - } else if ((Byte >= 'a' && Byte <= 'z') || (Byte >= 'A' && Byte <= 'Z') || - (Byte >= '0' && Byte <= '9') || Byte == '_' || Byte == '$') { + if ((Byte >= 'a' && Byte <= 'z') || (Byte >= 'A' && Byte <= 'Z') || + (Byte >= '0' && Byte <= '9') || Byte == '_' || Byte == '$') { Mangler.getStream() << Byte; } else if (Byte >= '\xe1' && Byte <= '\xfa') { - Mangler.getStream() << '?' << (char)('a' + Byte - '\xe1'); + Mangler.getStream() << '?' << static_cast<char>('a' + (Byte - '\xe1')); } else if (Byte >= '\xc1' && Byte <= '\xda') { - Mangler.getStream() << '?' << (char)('A' + Byte - '\xc1'); + Mangler.getStream() << '?' << static_cast<char>('A' + (Byte - '\xc1')); } else { - Mangler.getStream() << "?$"; - Mangler.getStream() << (char)('A' + ((Byte >> 4) & 0xf)); - Mangler.getStream() << (char)('A' + (Byte & 0xf)); + switch (Byte) { + case ',': + Mangler.getStream() << "?0"; + break; + case '/': + Mangler.getStream() << "?1"; + break; + case '\\': + Mangler.getStream() << "?2"; + break; + case ':': + Mangler.getStream() << "?3"; + break; + case '.': + Mangler.getStream() << "?4"; + break; + case ' ': + Mangler.getStream() << "?5"; + break; + case '\n': + Mangler.getStream() << "?6"; + break; + case '\t': + Mangler.getStream() << "?7"; + break; + case '\'': + Mangler.getStream() << "?8"; + break; + case '-': + Mangler.getStream() << "?9"; + break; + default: + Mangler.getStream() << "?$"; + Mangler.getStream() << static_cast<char>('A' + ((Byte >> 4) & 0xf)); + Mangler.getStream() << static_cast<char>('A' + (Byte & 0xf)); + break; + } } }; - // Enforce our 32 character max. - unsigned MaxBytes = 32 * SL->getCharByteWidth(); - StringRef Bytes = SL->getBytes().substr(0, MaxBytes); - size_t BytesLength = Bytes.size(); - - if (SL->isAscii()) { - // A character maps directly to a byte for ASCII StringLiterals. - for (char Byte : Bytes) - MangleCharacter(Byte); - } else if (SL->isWide()) { - // The ordering of bytes in a wide StringLiteral is like so: - // A B C D ... - // However, they are mangled in the following order: - // B A D C ... - for (size_t i = 0; i != BytesLength;) { - char FirstByte = Bytes[i]; - ++i; - if (i != BytesLength) { - char SecondByte = Bytes[i]; - ++i; - MangleCharacter(SecondByte); - } - MangleCharacter(FirstByte); + auto MangleChar = [&Mangler, &MangleByte, &SL](uint32_t CodeUnit) { + if (SL->getCharByteWidth() == 1) { + MangleByte(static_cast<char>(CodeUnit)); + } else if (SL->getCharByteWidth() == 2) { + MangleByte(static_cast<char>((CodeUnit >> 16) & 0xff)); + MangleByte(static_cast<char>(CodeUnit & 0xff)); + } else { + llvm_unreachable("unsupported CharByteWidth"); } - } else { - llvm_unreachable("unexpected string literal kind!"); - // TODO: This needs to be updated when MSVC gains support for Unicode - // literals. - } + }; - // We should also encode the NUL terminator(s) if we encoded less than 32 - // characters. - if (BytesLength < MaxBytes) { - size_t PaddingBytes = SL->getCharByteWidth(); - size_t BytesLeft = MaxBytes - BytesLength; - if (BytesLeft < PaddingBytes) - PaddingBytes = BytesLeft; - for (unsigned i = 0; i < PaddingBytes; ++i) - MangleCharacter('\x00'); - } + // Enforce our 32 character max. + unsigned NumCharsToMangle = std::min(32U, SL->getLength()); + for (unsigned i = 0; i < NumCharsToMangle; ++i) + MangleChar(SL->getCodeUnit(i)); + + // Encode the NUL terminator if there is room. + if (NumCharsToMangle < 32) + MangleChar(0); Mangler.getStream() << '@'; } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 097e30c71d1..e5a0fa56447 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2595,21 +2595,17 @@ CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S) { } if (!GV) { + SmallString<256> MangledNameBuffer; StringRef GlobalVariableName; llvm::GlobalValue::LinkageTypes LT; if (!LangOpts.WritableStrings && getCXXABI().getMangleContext().shouldMangleStringLiteral(S)) { - LT = llvm::GlobalValue::LinkOnceODRLinkage; - - SmallString<256> Buffer; - llvm::raw_svector_ostream Out(Buffer); + llvm::raw_svector_ostream Out(MangledNameBuffer); getCXXABI().getMangleContext().mangleStringLiteral(S, Out); Out.flush(); - size_t Length = Buffer.size(); - char *Name = MangledNamesAllocator.Allocate<char>(Length); - std::copy(Buffer.begin(), Buffer.end(), Name); - GlobalVariableName = StringRef(Name, Length); + LT = llvm::GlobalValue::LinkOnceODRLinkage; + GlobalVariableName = MangledNameBuffer; } else { LT = llvm::GlobalValue::PrivateLinkage;; GlobalVariableName = ".str"; |