]> granicus.if.org Git - clang/commitdiff
MS ABI: Mangle char16_t and char32_t string literals
authorDavid Majnemer <david.majnemer@gmail.com>
Fri, 21 Nov 2014 19:57:25 +0000 (19:57 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Fri, 21 Nov 2014 19:57:25 +0000 (19:57 +0000)
We previously had support for char and wchar_t string literals.  VS 2015
added support for char16_t and char32_t.

String literals must be mangled in the MS ABI in order for them to be
deduplicated across translation units: their linker has no notion of
mergeable section.  Instead, they use the mangled name to make a COMDAT
for the string literal; the COMDAT will merge with other COMDATs in
other object files.

This allows strings in object files generated by clang to get merged
with strings in object files generated by MSVC.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@222564 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/MicrosoftMangle.cpp
test/CodeGenCXX/mangle-ms-string-literals.cpp

index e1d47c20983f988577e36cceeb28dbea00aabffb..0530ca1be435882d4d1411482e75020a326aa755 100644 (file)
@@ -338,9 +338,7 @@ bool MicrosoftMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) {
 
 bool
 MicrosoftMangleContextImpl::shouldMangleStringLiteral(const StringLiteral *SL) {
-  return SL->isAscii() || SL->isWide();
-  // TODO: This needs to be updated when MSVC gains support for Unicode
-  // literals.
+  return SL->isAscii() || SL->isWide() || SL->isUTF16() || SL->isUTF32();
 }
 
 void MicrosoftCXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) {
@@ -2439,14 +2437,10 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
   Mangler.getStream() << "\01??_C@_";
 
   // <char-type>: The "kind" of string literal is encoded into the mangled name.
-  // TODO: This needs to be updated when MSVC gains support for unicode
-  // literals.
-  if (SL->isAscii())
-    Mangler.getStream() << '0';
-  else if (SL->isWide())
+  if (SL->isWide())
     Mangler.getStream() << '1';
   else
-    llvm_unreachable("unexpected string literal kind!");
+    Mangler.getStream() << '0';
 
   // <literal-length>: The next part of the mangled name consists of the length
   // of the string.
@@ -2569,7 +2563,10 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
   unsigned NumCharsToMangle = std::min(32U, SL->getLength());
   for (unsigned I = 0, E = NumCharsToMangle * SL->getCharByteWidth(); I != E;
        ++I)
-    MangleByte(GetBigEndianByte(I));
+    if (SL->isWide())
+      MangleByte(GetBigEndianByte(I));
+    else
+      MangleByte(GetLittleEndianByte(I));
 
   // Encode the NUL terminator if there is room.
   if (NumCharsToMangle < 32)
index a77a04f71e0a1cc34c53c00271604e5656a84357..a282190de4843fec763ba6570f75f8b4cac9f833 100644 (file)
@@ -719,3 +719,7 @@ const wchar_t *LongWideString = L"012345678901234567890123456789ABCDEF";
 // CHECK: @"\01??_C@_1EK@KFPEBLPK@?$AA0?$AA1?$AA2?$AA3?$AA4?$AA5?$AA6?$AA7?$AA8?$AA9?$AA0?$AA1?$AA2?$AA3?$AA4?$AA5?$AA6?$AA7?$AA8?$AA9?$AA0?$AA1?$AA2?$AA3?$AA4?$AA5?$AA6?$AA7?$AA8?$AA9?$AAA?$AAB@"
 const wchar_t *UnicodeLiteral = L"\ud7ff";
 // CHECK: @"\01??_C@_13IIHIAFKH@?W?$PP?$AA?$AA@"
+const char16_t *U16Literal = u"hi";
+// CHECK: @"\01??_C@_05OMLEGLOC@h?$AAi?$AA?$AA?$AA@"
+const char32_t *U32Literal = U"hi";
+// CHECK: @"\01??_C@_0M@GFNAJIPG@h?$AA?$AA?$AAi?$AA?$AA?$AA?$AA?$AA?$AA?$AA@"