forked from OSchip/llvm-project
Handle UTF-16 and UTF-32 constant CFStrings
We have a longstanding issue where the expression parser does not handle wide CFStrings (e.g., @"凸凹") correctly, producing the useless error message Internal error [IRForTarget]: An Objective-C constant string's string initializer is not an array error: warning: expression result unused error: The expression could not be prepared to run in the target This is just a side effect of the fact that we don't handle wide string constants when converting these to CFStringCreateWithBytes. That function takes the string's encoding as an argument, so I made it work and added a testcase. https://reviews.llvm.org/D27291 <rdar://problem/13190557> llvm-svn: 288386
This commit is contained in:
parent
93f12aff55
commit
cd1eb72bab
|
@ -0,0 +1,6 @@
|
|||
from lldbsuite.test import lldbinline
|
||||
from lldbsuite.test import decorators
|
||||
|
||||
lldbinline.MakeInlineTest(
|
||||
__file__, globals(), [
|
||||
decorators.skipUnlessDarwin])
|
|
@ -0,0 +1,5 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
int main() {
|
||||
NSLog(@"凸"); //% self.expect("po @\"凹\"", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["凹"])
|
||||
}
|
|
@ -498,9 +498,27 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
|
|||
Constant *bytes_arg = cstr ? ConstantExpr::getBitCast(cstr, i8_ptr_ty)
|
||||
: Constant::getNullValue(i8_ptr_ty);
|
||||
Constant *numBytes_arg = ConstantInt::get(
|
||||
m_intptr_ty, cstr ? string_array->getNumElements() - 1 : 0, false);
|
||||
Constant *encoding_arg = ConstantInt::get(
|
||||
i32_ty, 0x0600, false); /* 0x0600 is kCFStringEncodingASCII */
|
||||
m_intptr_ty, cstr ? (string_array->getNumElements() - 1) * string_array->getElementByteSize() : 0, false);
|
||||
int encoding_flags = 0;
|
||||
switch (string_array->getElementByteSize()) {
|
||||
case 1:
|
||||
encoding_flags = 0x08000100; /* 0x08000100 is kCFStringEncodingUTF8 */
|
||||
break;
|
||||
case 2:
|
||||
encoding_flags = 0x0100; /* 0x0100 is kCFStringEncodingUTF16 */
|
||||
break;
|
||||
case 4:
|
||||
encoding_flags = 0x0c000100; /* 0x0c000100 is kCFStringEncodingUTF32 */
|
||||
break;
|
||||
default:
|
||||
encoding_flags = 0x0600; /* fall back to 0x0600, kCFStringEncodingASCII */
|
||||
if (log) {
|
||||
log->Printf("Encountered an Objective-C constant string with unusual "
|
||||
"element size %llu",
|
||||
string_array->getElementByteSize());
|
||||
}
|
||||
}
|
||||
Constant *encoding_arg = ConstantInt::get(i32_ty, encoding_flags, false);
|
||||
Constant *isExternal_arg =
|
||||
ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */
|
||||
|
||||
|
@ -523,8 +541,8 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
|
|||
m_entry_instruction_finder.GetValue(function)));
|
||||
});
|
||||
|
||||
if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller,
|
||||
m_entry_instruction_finder, m_error_stream)) {
|
||||
if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller, m_entry_instruction_finder,
|
||||
m_error_stream)) {
|
||||
if (log)
|
||||
log->PutCString(
|
||||
"Couldn't replace the NSString with the result of the call");
|
||||
|
@ -642,31 +660,23 @@ bool IRForTarget::RewriteObjCConstStrings() {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (nsstring_expr->getOpcode() != Instruction::GetElementPtr) {
|
||||
if (log)
|
||||
log->Printf("NSString initializer's str element is not a "
|
||||
"GetElementPtr expression, it's a %s",
|
||||
nsstring_expr->getOpcodeName());
|
||||
|
||||
m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
|
||||
"constant string's string initializer is not an "
|
||||
"array\n");
|
||||
|
||||
return false;
|
||||
}
|
||||
GlobalVariable *cstr_global = nullptr;
|
||||
|
||||
if (nsstring_expr->getOpcode() == Instruction::GetElementPtr) {
|
||||
Constant *nsstring_cstr = nsstring_expr->getOperand(0);
|
||||
|
||||
GlobalVariable *cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
|
||||
cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
|
||||
} else if (nsstring_expr->getOpcode() == Instruction::BitCast) {
|
||||
Constant *nsstring_cstr = nsstring_expr->getOperand(0);
|
||||
cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
|
||||
}
|
||||
|
||||
if (!cstr_global) {
|
||||
if (log)
|
||||
log->PutCString(
|
||||
"NSString initializer's str element is not a GlobalVariable");
|
||||
|
||||
m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
|
||||
"constant string's string initializer doesn't "
|
||||
"point to a global\n");
|
||||
m_error_stream.Printf("Internal error [IRForTarget]: Unhandled"
|
||||
"constant string initializer\n");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue