summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-03-24 05:53:08 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-03-24 05:53:08 +0000
commit96bc4b03676655383766ca2337245a8d82f58403 (patch)
tree245207c6cac977543c4eb0b32f7a6783f56a0f18 /clang/lib
parent016d69d29feaa45f10c097e27a081cfa93fe0e2a (diff)
downloadbcm5719-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.cpp115
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp12
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";
OpenPOWER on IntegriCloud