[Lldb-commits] [lldb] r288386 - Handle UTF-16 and UTF-32 constant CFStrings
Sean Callanan via lldb-commits
lldb-commits at lists.llvm.org
Thu Dec 1 09:46:51 PST 2016
Author: spyffe
Date: Thu Dec 1 11:46:51 2016
New Revision: 288386
URL: http://llvm.org/viewvc/llvm-project?rev=288386&view=rev
Log:
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>
Added:
lldb/trunk/packages/Python/lldbsuite/test/lang/objc/unicode-string/
lldb/trunk/packages/Python/lldbsuite/test/lang/objc/unicode-string/TestUnicodeString.py
lldb/trunk/packages/Python/lldbsuite/test/lang/objc/unicode-string/main.m
Modified:
lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
Added: lldb/trunk/packages/Python/lldbsuite/test/lang/objc/unicode-string/TestUnicodeString.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/objc/unicode-string/TestUnicodeString.py?rev=288386&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/objc/unicode-string/TestUnicodeString.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/objc/unicode-string/TestUnicodeString.py Thu Dec 1 11:46:51 2016
@@ -0,0 +1,6 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(
+ __file__, globals(), [
+ decorators.skipUnlessDarwin])
Added: lldb/trunk/packages/Python/lldbsuite/test/lang/objc/unicode-string/main.m
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/objc/unicode-string/main.m?rev=288386&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/objc/unicode-string/main.m (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/objc/unicode-string/main.m Thu Dec 1 11:46:51 2016
@@ -0,0 +1,5 @@
+#import <Foundation/Foundation.h>
+
+int main() {
+ NSLog(@"å¸"); //% self.expect("po @\"å¹\"", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["å¹"])
+}
Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp?rev=288386&r1=288385&r2=288386&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp Thu Dec 1 11:46:51 2016
@@ -498,42 +498,60 @@ bool IRForTarget::RewriteObjCConstString
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 */
- Constant *isExternal_arg =
- ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */
-
- Value *argument_array[5];
-
- argument_array[0] = alloc_arg;
- argument_array[1] = bytes_arg;
- argument_array[2] = numBytes_arg;
- argument_array[3] = encoding_arg;
- argument_array[4] = isExternal_arg;
-
- ArrayRef<Value *> CFSCWB_arguments(argument_array, 5);
-
- FunctionValueCache CFSCWB_Caller(
- [this, &CFSCWB_arguments](llvm::Function *function) -> llvm::Value * {
- return CallInst::Create(
- m_CFStringCreateWithBytes, CFSCWB_arguments,
- "CFStringCreateWithBytes",
- llvm::cast<Instruction>(
- m_entry_instruction_finder.GetValue(function)));
- });
-
- 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");
-
- m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an "
- "Objective-C constant string with a dynamic "
- "string\n");
+ 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 */
+
+ Value *argument_array[5];
+
+ argument_array[0] = alloc_arg;
+ argument_array[1] = bytes_arg;
+ argument_array[2] = numBytes_arg;
+ argument_array[3] = encoding_arg;
+ argument_array[4] = isExternal_arg;
+
+ ArrayRef<Value *> CFSCWB_arguments(argument_array, 5);
+
+ FunctionValueCache CFSCWB_Caller(
+ [this, &CFSCWB_arguments](llvm::Function *function) -> llvm::Value * {
+ return CallInst::Create(
+ m_CFStringCreateWithBytes, CFSCWB_arguments,
+ "CFStringCreateWithBytes",
+ llvm::cast<Instruction>(
+ m_entry_instruction_finder.GetValue(function)));
+ });
+
+ 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");
+
+ m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an "
+ "Objective-C constant string with a dynamic "
+ "string\n");
- return false;
+ return false;
}
ns_str->eraseFromParent();
@@ -642,31 +660,23 @@ bool IRForTarget::RewriteObjCConstString
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");
+ GlobalVariable *cstr_global = nullptr;
- return false;
+ if (nsstring_expr->getOpcode() == Instruction::GetElementPtr) {
+ Constant *nsstring_cstr = nsstring_expr->getOperand(0);
+ 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);
}
- Constant *nsstring_cstr = nsstring_expr->getOperand(0);
-
- GlobalVariable *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;
}
More information about the lldb-commits
mailing list