diff options
author | Bill Wendling <isanbard@gmail.com> | 2012-03-30 00:26:17 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2012-03-30 00:26:17 +0000 |
commit | 82b87f19e22a8bd53d3e1faa9cf3029daa0bac5b (patch) | |
tree | b471424710c2b5f406072aff6fc5cd0fcf2c7ba4 /clang/lib/CodeGen/CodeGenModule.cpp | |
parent | ab468b03815a8454b4bda1e5b4f20bc1ad7f1857 (diff) | |
download | bcm5719-llvm-82b87f19e22a8bd53d3e1faa9cf3029daa0bac5b.tar.gz bcm5719-llvm-82b87f19e22a8bd53d3e1faa9cf3029daa0bac5b.zip |
The UTF16 string referenced by a CFString should go into the __TEXT,__ustring
section. A 'normal' string will go into the __TEXT,__const section, but this
isn't good for UTF16 strings. The __ustring section allows for coalescing, among
other niceties (such as allowing the linker to easily split up strings).
Instead of outputting the UTF16 string as a series of bytes, output it as a
series of shorts. The back-end will then nicely place the UTF16 string into the
correct section, because it's a mensch.
<rdar://problem/10655949>
llvm-svn: 153710
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 50 |
1 files changed, 24 insertions, 26 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 6fa33b6c122..c9f1066032d 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1903,8 +1903,10 @@ GetConstantCFStringEntry(llvm::StringMap<llvm::Constant*> &Map, return Map.GetOrCreateValue(String); } - // Otherwise, convert the UTF8 literals into a byte string. - SmallVector<UTF16, 128> ToBuf(NumBytes); + // Otherwise, convert the UTF8 literals into a string of shorts. + IsUTF16 = true; + + SmallVector<UTF16, 128> ToBuf(NumBytes + 1); // +1 for ending nulls. const UTF8 *FromPtr = (UTF8 *)String.data(); UTF16 *ToPtr = &ToBuf[0]; @@ -1915,28 +1917,11 @@ GetConstantCFStringEntry(llvm::StringMap<llvm::Constant*> &Map, // ConvertUTF8toUTF16 returns the length in ToPtr. StringLength = ToPtr - &ToBuf[0]; - // Render the UTF-16 string into a byte array and convert to the target byte - // order. - // - // FIXME: This isn't something we should need to do here. - SmallString<128> AsBytes; - AsBytes.reserve(StringLength * 2); - for (unsigned i = 0; i != StringLength; ++i) { - unsigned short Val = ToBuf[i]; - if (TargetIsLSB) { - AsBytes.push_back(Val & 0xFF); - AsBytes.push_back(Val >> 8); - } else { - AsBytes.push_back(Val >> 8); - AsBytes.push_back(Val & 0xFF); - } - } - // Append one extra null character, the second is automatically added by our - // caller. - AsBytes.push_back(0); - - IsUTF16 = true; - return Map.GetOrCreateValue(StringRef(AsBytes.data(), AsBytes.size())); + // Add an explicit null. + *ToPtr = 0; + return Map. + GetOrCreateValue(StringRef(reinterpret_cast<const char *>(ToBuf.data()), + (StringLength + 1) * 2)); } static llvm::StringMapEntry<llvm::Constant*> & @@ -1990,8 +1975,15 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { llvm::ConstantInt::get(Ty, 0x07C8); // String pointer. - llvm::Constant *C = llvm::ConstantDataArray::getString(VMContext, - Entry.getKey()); + llvm::Constant *C = 0; + if (isUTF16) { + ArrayRef<uint16_t> Arr = + llvm::makeArrayRef<uint16_t>((uint16_t*)Entry.getKey().data(), + Entry.getKey().size() / 2); + C = llvm::ConstantDataArray::get(VMContext, Arr); + } else { + C = llvm::ConstantDataArray::getString(VMContext, Entry.getKey()); + } llvm::GlobalValue::LinkageTypes Linkage; if (isUTF16) @@ -2016,8 +2008,14 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { CharUnits Align = getContext().getTypeAlignInChars(getContext().CharTy); GV->setAlignment(Align.getQuantity()); } + + // String. Fields[2] = llvm::ConstantExpr::getGetElementPtr(GV, Zeros); + if (isUTF16) + // Cast the UTF16 string to the correct type. + Fields[2] = llvm::ConstantExpr::getBitCast(Fields[2], Int8PtrTy); + // String length. Ty = getTypes().ConvertType(getContext().LongTy); Fields[3] = llvm::ConstantInt::get(Ty, StringLength); |