Add ConvertUTF module from http://www.unicode.org/Public/PROGRAMS/CVTUTF.

#ifdef'd out the 5 conversion routines that we don't currently need.

Still need a bit more work in GetAddrOfConstantCFString(). Added a FIXME to indicate this.

Expect to remove the FIXME today...


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68208 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index d428c83..2e84c60 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -24,6 +24,7 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/ConvertUTF.h"
 #include "llvm/CallingConv.h"
 #include "llvm/Module.h"
 #include "llvm/Intrinsics.h"
@@ -1003,9 +1004,21 @@
 // See: <rdr://2996215>
 llvm::Constant *CodeGenModule::
 GetAddrOfConstantCFString(const StringLiteral *Literal) {
-  //  if (Literal->containsNonAsciiOrNull()) {
-  //    // FIXME: Convert from UTF-8 to UTF-16.
-  //  }
+  bool isUTF16 = false;
+  if (Literal->containsNonAsciiOrNull()) {
+    // Convert from UTF-8 to UTF-16.
+    llvm::SmallVector<UTF16, 128> ToBuf(Literal->getByteLength());
+    const UTF8 *FromPtr = (UTF8 *)Literal->getStrData();
+    UTF16 *ToPtr = &ToBuf[0];
+        
+    ConversionResult Result;
+    Result = ConvertUTF8toUTF16(&FromPtr, FromPtr+Literal->getByteLength(),
+                                &ToPtr, ToPtr+Literal->getByteLength(),
+                                strictConversion);
+    assert(Result == conversionOK && "UTF-8 to UTF-16 conversion failed");
+    isUTF16 = true;
+    // FIXME: Do something with the converted value!
+  }
   std::string str(Literal->getStrData(), Literal->getByteLength());
   llvm::StringMapEntry<llvm::Constant *> &Entry = 
     CFConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]);
@@ -1056,7 +1069,9 @@
   NextField = *Field++;
   const llvm::Type *Ty = getTypes().ConvertType(getContext().UnsignedIntTy);
   appendFieldAndPadding(*this, Fields, CurField, NextField,
-                        llvm::ConstantInt::get(Ty, 0x07C8), CFRD, STy);
+                        isUTF16 ? llvm::ConstantInt::get(Ty, 0x07d0)
+                                : llvm::ConstantInt::get(Ty, 0x07C8), 
+                        CFRD, STy);
     
   // String pointer.
   CurField = NextField;