Add clang support for new Objective-C literal syntax for NSDictionary, NSArray,
NSNumber, and boolean literals.  This includes both Sema and Codegen support.
Included is also support for new Objective-C container subscripting.

My apologies for the large patch.  It was very difficult to break apart.
The patch introduces changes to the driver as well to cause clang to link
in additional runtime support when needed to support the new language features.

Docs are forthcoming to document the implementation and behavior of these features.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152137 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGenObjC/Inputs/literal-support.h b/test/CodeGenObjC/Inputs/literal-support.h
new file mode 100644
index 0000000..5680a20
--- /dev/null
+++ b/test/CodeGenObjC/Inputs/literal-support.h
@@ -0,0 +1,35 @@
+#ifndef OBJC_LITERAL_SUPPORT_H
+#define OBJC_LITERAL_SUPPORT_H
+
+typedef unsigned char BOOL;
+
+@interface NSNumber @end
+
+@interface NSNumber (NSNumberCreation)
++ (NSNumber *)numberWithChar:(char)value;
++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
++ (NSNumber *)numberWithShort:(short)value;
++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
++ (NSNumber *)numberWithInt:(int)value;
++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
++ (NSNumber *)numberWithLong:(long)value;
++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
++ (NSNumber *)numberWithLongLong:(long long)value;
++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
++ (NSNumber *)numberWithFloat:(float)value;
++ (NSNumber *)numberWithDouble:(double)value;
++ (NSNumber *)numberWithBool:(BOOL)value;
+@end
+
+@interface NSArray
+@end
+
+@interface NSArray (NSArrayCreation)
++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
+@end
+
+@interface NSDictionary
++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
+@end
+
+#endif // OBJC_LITERAL_SUPPORT_H
diff --git a/test/CodeGenObjC/arc-literals.m b/test/CodeGenObjC/arc-literals.m
new file mode 100644
index 0000000..203c2ad
--- /dev/null
+++ b/test/CodeGenObjC/arc-literals.m
@@ -0,0 +1,121 @@
+// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+
+#include "literal-support.h"
+
+// Check the various selector names we'll be using, in order.
+
+// CHECK: c"numberWithInt:\00"
+// CHECK: c"numberWithUnsignedInt:\00"
+// CHECK: c"numberWithUnsignedLongLong:\00"
+// CHECK: c"numberWithChar:\00"
+// CHECK: c"arrayWithObjects:count:\00"
+// CHECK: c"dictionaryWithObjects:forKeys:count:\00"
+// CHECK: c"prop\00"
+
+// CHECK: define void @test_numeric()
+void test_numeric() {
+  // CHECK: {{call.*objc_msgSend.*i32 17}}
+  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+  id ilit = @17;
+  // CHECK: {{call.*objc_msgSend.*i32 25}}
+  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+  id ulit = @25u;
+  // CHECK: {{call.*objc_msgSend.*i64 42}}
+  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+  id ulllit = @42ull;
+  // CHECK: {{call.*objc_msgSend.*i8 signext 97}}
+  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+  id charlit = @'a';
+  // CHECK: call void @objc_release
+  // CHECK: call void @objc_release
+  // CHECK: call void @objc_release
+  // CHECK: call void @objc_release
+  // CHECK-NEXT: ret void
+}
+
+// CHECK: define void @test_array
+void test_array(id a, id b) {
+  // Retaining parameters
+  // CHECK: call i8* @objc_retain(i8*
+  // CHECK: call i8* @objc_retain(i8*
+
+  // Constructing the array
+  // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i32 0, i32 0
+  // CHECK: store i8*
+  // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1
+  // CHECK: store i8*
+
+  // CHECK: {{call i8*.*objc_msgSend.*i64 2}}
+  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+  id arr = @[a, b];
+
+  // CHECK: call void @objc_release
+  // CHECK: call void @objc_release
+  // CHECK: call void @objc_release
+  // CHECK-NEXT: ret void
+}
+
+// CHECK: define void @test_dictionary
+void test_dictionary(id k1, id o1, id k2, id o2) {
+  // Retaining parameters
+  // CHECK: call i8* @objc_retain(i8*
+  // CHECK: call i8* @objc_retain(i8*
+  // CHECK: call i8* @objc_retain(i8*
+  // CHECK: call i8* @objc_retain(i8*
+
+  // Constructing the arrays
+  // CHECK: getelementptr inbounds [2 x i8*]* [[KEYS:%[A-Za-z0-9]+]], i32 0, i32 0
+  // CHECK: store i8*
+  // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i32 0, i32 0
+  // CHECK: store i8*
+  // CHECK: getelementptr inbounds [2 x i8*]* [[KEYS]], i32 0, i32 1
+  // CHECK: store i8*
+  // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1
+  // CHECK: store i8*
+
+  // Constructing the dictionary
+  // CHECK: {{call i8.*@objc_msgSend}}
+  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+  id dict = @{ k1 : o1, k2 : o2 };
+
+  // CHECK: call void @objc_release
+  // CHECK: call void @objc_release
+  // CHECK: call void @objc_release
+  // CHECK: call void @objc_release
+  // CHECK: call void @objc_release
+  // CHECK-NEXT: ret void
+}
+
+@interface A
+@end
+
+@interface B
+@property (retain) A* prop;
+@end
+
+// CHECK: define void @test_property
+void test_property(B *b) {
+  // Retain parameter
+  // CHECK: call i8* @objc_retain
+
+  // Invoke 'prop'
+  // CHECK: load i8** @"\01L_OBJC_SELECTOR_REFERENCES
+  // CHECK: {{call.*@objc_msgSend}}
+  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+
+  // Invoke arrayWithObjects:count:
+  // CHECK: load i8** @"\01L_OBJC_SELECTOR_REFERENCES
+  // CHECK: {{call.*objc_msgSend}}
+  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+  id arr = @[ b.prop ];
+
+  // Release b.prop
+  // CHECK: call void @objc_release
+
+  // Destroy arr
+  // CHECK: call void @objc_release
+
+  // Destroy b
+  // CHECK: call void @objc_release
+  // CHECK-NEXT: ret void
+}
diff --git a/test/CodeGenObjC/objc-arc-container-subscripting.m b/test/CodeGenObjC/objc-arc-container-subscripting.m
new file mode 100644
index 0000000..8924916
--- /dev/null
+++ b/test/CodeGenObjC/objc-arc-container-subscripting.m
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fobjc-arc -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s
+
+@interface NSMutableArray
+- (id)objectAtIndexedSubscript:(int)index;
+- (void)setObject:(id)object atIndexedSubscript:(int)index;
+@end
+
+id func() {
+  NSMutableArray *array;
+  array[3] = 0;
+  return array[3];
+}
+
+// CHECK: [[call:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
+// CHECK: [[SIX:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[call]]) nounwind
+// CHECK: [[ARRAY:%.*]] = load %0** 
+// CHECK: [[ARRAY_CASTED:%.*]] = bitcast{{.*}}[[ARRAY]] to i8*
+// CHECK: call void @objc_release(i8* [[ARRAY_CASTED]])
+// CHECK: [[EIGHT:%.*]] = call i8* @objc_autoreleaseReturnValue(i8* [[SIX]]) nounwind
+// CHECK: ret i8* [[EIGHT]]
+
diff --git a/test/CodeGenObjC/objc-container-subscripting-1.m b/test/CodeGenObjC/objc-container-subscripting-1.m
new file mode 100644
index 0000000..91b7f46
--- /dev/null
+++ b/test/CodeGenObjC/objc-container-subscripting-1.m
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s
+
+typedef unsigned int size_t;
+@protocol P @end
+
+@interface NSMutableArray
+- (id)objectAtIndexedSubscript:(size_t)index;
+- (void)setObject:(id)object atIndexedSubscript:(size_t)index;
+@end
+
+@interface NSMutableDictionary
+- (id)objectForKeyedSubscript:(id)key;
+- (void)setObject:(id)object forKeyedSubscript:(id)key;
+@end
+
+int main() {
+  NSMutableArray *array;
+  id val;
+
+  id oldObject = array[10];
+// CHECK: [[ARR:%.*]] = load {{%.*}} [[array:%.*]], align 8
+// CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_"
+// CHECK-NEXT: [[ARRC:%.*]] = bitcast {{%.*}} [[ARR]] to i8*
+// CHECK-NEXT: [[CALL:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i32)*)(i8* [[ARRC]], i8* [[SEL]], i32 10)
+// CHECK-NEXT: store i8* [[CALL]], i8** [[OLDOBJ:%.*]], align 8
+
+  val = (array[10] = oldObject);
+// CHECK: [[THREE:%.*]] = load {{%.*}} [[array:%.*]], align 8
+// CHECK-NEXT: [[FOUR:%.*]] = load i8** [[oldObject:%.*]], align 8
+// CHECK-NEXT: [[FIVE:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_2"
+// CHECK-NEXT: [[SIX:%.*]] = bitcast {{%.*}} [[THREE]] to i8*
+// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*, i32)*)(i8* [[SIX]], i8* [[FIVE]], i8* [[FOUR]], i32 10)
+// CHECK-NEXT: store i8* [[FOUR]], i8** [[val:%.*]]
+
+  NSMutableDictionary *dictionary;
+  id key;
+  id newObject;
+  oldObject = dictionary[key];
+// CHECK:  [[SEVEN:%.*]] = load {{%.*}} [[DICTIONARY:%.*]], align 8
+// CHECK-NEXT:  [[EIGHT:%.*]] = load i8** [[KEY:%.*]], align 8
+// CHECK-NEXT:  [[TEN:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_4"
+// CHECK-NEXT:  [[ELEVEN:%.*]] = bitcast {{%.*}} [[SEVEN]] to i8*
+// CHECK-NEXT:  [[CALL1:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* [[ELEVEN]], i8* [[TEN]], i8* [[EIGHT]])
+// CHECK-NEXT:  store i8* [[CALL1]], i8** [[oldObject:%.*]], align 8
+
+
+  val = (dictionary[key] = newObject);
+// CHECK: [[TWELVE:%.*]] = load {{%.*}} [[DICTIONARY]], align 8
+// CHECK-NEXT:  [[THIRTEEN:%.*]] = load i8** [[KEY]], align 8
+// CHECK-NEXT:  [[FOURTEEN:%.*]] = load i8** [[NEWOBJECT:%.*]], align 8
+// CHECK-NEXT:  [[SIXTEEN:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_6"
+// CHECK-NEXT:  [[SEVENTEEN:%.*]] = bitcast {{%.*}} [[TWELVE]] to i8*
+// CHECK-NEXT:  call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*, i8*)*)(i8* [[SEVENTEEN]], i8* [[SIXTEEN]], i8* [[FOURTEEN]], i8* [[THIRTEEN]])
+// CHECK-NEXT: store i8* [[FOURTEEN]], i8** [[val:%.*]]
+}
+
diff --git a/test/CodeGenObjC/objc-container-subscripting.m b/test/CodeGenObjC/objc-container-subscripting.m
new file mode 100644
index 0000000..fd8f8ef
--- /dev/null
+++ b/test/CodeGenObjC/objc-container-subscripting.m
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin %s -o /dev/null
+
+typedef unsigned int size_t;
+@protocol P @end
+
+@interface NSMutableArray
+#if __has_feature(objc_subscripting)
+- (id)objectAtIndexedSubscript:(size_t)index;
+- (void)setObject:(id)object atIndexedSubscript:(size_t)index;
+#endif
+@end
+
+#if __has_feature(objc_subscripting)
+@interface XNSMutableArray
+- (id)objectAtIndexedSubscript:(size_t)index;
+- (void)setObject:(id)object atIndexedSubscript:(size_t)index;
+#endif
+@end
+
+@interface NSMutableDictionary
+- (id)objectForKeyedSubscript:(id)key;
+- (void)setObject:(id)object forKeyedSubscript:(id)key;
+@end
+
+@class NSString;
+
+int main() {
+  NSMutableArray<P> * array;
+  id oldObject = array[10];
+ 
+  array[10] = oldObject;
+
+  id unknown_array;
+  oldObject = unknown_array[1];
+
+  unknown_array[1] = oldObject;
+
+  NSMutableDictionary *dictionary;
+  NSString *key;
+  id newObject;
+  oldObject = dictionary[key];
+  dictionary[key] = newObject;	// replace oldObject with newObject
+
+}
+
diff --git a/test/CodeGenObjC/objc-dictionary-literal.m b/test/CodeGenObjC/objc-dictionary-literal.m
new file mode 100644
index 0000000..b335582
--- /dev/null
+++ b/test/CodeGenObjC/objc-dictionary-literal.m
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -x objective-c -triple x86_64-apple-darwin10 -fblocks -emit-llvm %s -o /dev/null
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fblocks -emit-llvm %s -o /dev/null
+// rdar://10614657
+
+@interface NSNumber
++ (NSNumber *)numberWithChar:(char)value;
++ (NSNumber *)numberWithInt:(int)value;
+@end
+
+@protocol NSCopying @end
+typedef unsigned long NSUInteger;
+
+@interface NSDictionary
++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt;
+@end
+
+@interface NSString<NSCopying>
+@end
+
+int main() {
+	NSDictionary *dict = @{ @"name":@666 };
+	NSDictionary *dict1 = @{ @"name":@666 };
+	NSDictionary *dict2 = @{ @"name":@666 };
+	return 0;
+}
diff --git a/test/CodeGenObjC/objc-literal-debugger-test.m b/test/CodeGenObjC/objc-literal-debugger-test.m
new file mode 100644
index 0000000..389ef22
--- /dev/null
+++ b/test/CodeGenObjC/objc-literal-debugger-test.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fdebugger-objc-literal -emit-llvm -o - %s | FileCheck %s
+
+int main() {
+  id l = @'a';
+  l = @'a';
+  l = @42;
+  l = @-42;
+  l = @42u;
+  l = @3.141592654f;
+  l = @__objc_yes;
+  l = @__objc_no;
+  l = @{ @"name":@666 };
+  l = @[ @"foo", @"bar" ];
+}
+
+// CHECK: declare i8* @objc_msgSend(i8*, i8*, ...) nonlazybind
diff --git a/test/CodeGenObjC/objc-literal-tests.m b/test/CodeGenObjC/objc-literal-tests.m
new file mode 100644
index 0000000..c513d49
--- /dev/null
+++ b/test/CodeGenObjC/objc-literal-tests.m
@@ -0,0 +1,95 @@
+// RUN: %clang_cc1 -x objective-c -triple x86_64-apple-darwin10 -fblocks -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fblocks -emit-llvm %s -o - | FileCheck %s
+// rdar://10111397
+
+#if __has_feature(objc_bool)
+#define YES __objc_yes
+#define NO __objc_no
+#else
+#define YES             ((BOOL)1)
+#define NO              ((BOOL)0)
+#endif
+
+#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
+typedef unsigned long NSUInteger;
+typedef long NSInteger;
+#else
+typedef unsigned int NSUInteger;
+typedef int NSInteger;
+#endif
+typedef signed char BOOL;
+
+@interface NSNumber @end
+
+@interface NSNumber (NSNumberCreation)
+#if __has_feature(objc_array_literals)
++ (NSNumber *)numberWithChar:(char)value;
++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
++ (NSNumber *)numberWithShort:(short)value;
++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
++ (NSNumber *)numberWithInt:(int)value;
++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
++ (NSNumber *)numberWithLong:(long)value;
++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
++ (NSNumber *)numberWithLongLong:(long long)value;
++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
++ (NSNumber *)numberWithFloat:(float)value;
++ (NSNumber *)numberWithDouble:(double)value;
++ (NSNumber *)numberWithBool:(BOOL)value;
++ (NSNumber *)numberWithInteger:(NSInteger)value ;
++ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value ;
+#endif
+@end
+
+@interface NSDate
++ (NSDate *) date;
+@end
+
+#if __has_feature(objc_dictionary_literals)
+@interface NSDictionary
++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(NSUInteger)cnt;
+@end
+#endif
+
+id NSUserName();
+
+// CHECK: define i32 @main() nounwind 
+int main() {
+  // CHECK: call{{.*}}@objc_msgSend{{.*}}i8 signext 97
+  NSNumber *aNumber = @'a';
+  // CHECK: call{{.*}}@objc_msgSend{{.*}}i32 42
+  NSNumber *fortyTwo = @42;
+  // CHECK: call{{.*}}@objc_msgSend{{.*}}i32 -42
+  NSNumber *negativeFortyTwo = @-42;
+  // CHECK: call{{.*}}@objc_msgSend{{.*}}i32 42
+  NSNumber *positiveFortyTwo = @+42;
+  // CHECK: call{{.*}}@objc_msgSend{{.*}}i32 42
+  NSNumber *fortyTwoUnsigned = @42u;
+  // CHECK: call{{.*}}@objc_msgSend{{.*}}i64 42
+  NSNumber *fortyTwoLong = @42l;
+  // CHECK: call{{.*}}@objc_msgSend{{.*}}i64 42
+  NSNumber *fortyTwoLongLong = @42ll;
+  // CHECK: call{{.*}}@objc_msgSend{{.*}}float 0x400921FB60000000
+  NSNumber *piFloat = @3.141592654f;
+  // CHECK: call{{.*}}@objc_msgSend{{.*}}double 0x400921FB54411744
+  NSNumber *piDouble = @3.1415926535;
+  // CHECK: call{{.*}}@objc_msgSend{{.*}}i8 signext 1
+  NSNumber *yesNumber = @__objc_yes;
+  // CHECK: call{{.*}}@objc_msgSend{{.*}}i8 signext 0
+  NSNumber *noNumber = @__objc_no;
+  // CHECK: call{{.*}}@objc_msgSend{{.*}}i8 signext 1
+  NSNumber *yesNumber1 = @YES;
+  // CHECK: call{{.*}}@objc_msgSend{{.*}}i8 signext 0
+  NSNumber *noNumber1 = @NO;
+NSDictionary *dictionary = @{@"name" : NSUserName(), 
+                             @"date" : [NSDate date] }; 
+  return __objc_yes == __objc_no;
+}
+
+// rdar://10579122
+typedef BOOL (^foo)(void);
+extern void bar(foo a);
+
+void baz(void) {
+  bar(^(void) { return YES; });
+}
diff --git a/test/CodeGenObjC/optimized-setter.m b/test/CodeGenObjC/optimized-setter.m
new file mode 100644
index 0000000..0e1b388
--- /dev/null
+++ b/test/CodeGenObjC/optimized-setter.m
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-apple-macosx10.8.0 -o - | FileCheck %s
+// rdar://10179974
+
+@interface I
+// void objc_setProperty_nonatomic(id self, SEL _cmd, id newValue, ptrdiff_t offset);
+// objc_setProperty(..., NO, NO) 
+@property (nonatomic, retain) id nonatomicProperty;
+
+// void objc_setProperty_nonatomic_copy(id self, SEL _cmd, id newValue, ptrdiff_t offset);
+// objc_setProperty(..., NO, YES)
+@property (nonatomic, copy) id nonatomicPropertyCopy;
+
+// void objc_setProperty_atomic(id self, SEL _cmd, id newValue, ptrdiff_t offset);
+// objc_setProperty(..., YES, NO)
+@property (retain) id atomicProperty;
+
+// void objc_setProperty_atomic_copy(id self, SEL _cmd, id newValue, ptrdiff_t offset);
+// objc_setProperty(..., YES, YES)
+@property (copy) id atomicPropertyCopy;
+@end
+
+@implementation I
+@synthesize nonatomicProperty;
+@synthesize nonatomicPropertyCopy;
+@synthesize atomicProperty;
+@synthesize atomicPropertyCopy;
+@end
+
+// CHECK: call void @objc_setProperty_nonatomic
+// CHECK: call void @objc_setProperty_nonatomic_copy
+// CHECK: call void @objc_setProperty_atomic
+// CHECK: call void @objc_setProperty_atomic_copy
+
diff --git a/test/CodeGenObjCXX/Inputs/literal-support.h b/test/CodeGenObjCXX/Inputs/literal-support.h
new file mode 100644
index 0000000..5680a20
--- /dev/null
+++ b/test/CodeGenObjCXX/Inputs/literal-support.h
@@ -0,0 +1,35 @@
+#ifndef OBJC_LITERAL_SUPPORT_H
+#define OBJC_LITERAL_SUPPORT_H
+
+typedef unsigned char BOOL;
+
+@interface NSNumber @end
+
+@interface NSNumber (NSNumberCreation)
++ (NSNumber *)numberWithChar:(char)value;
++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
++ (NSNumber *)numberWithShort:(short)value;
++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
++ (NSNumber *)numberWithInt:(int)value;
++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
++ (NSNumber *)numberWithLong:(long)value;
++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
++ (NSNumber *)numberWithLongLong:(long long)value;
++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
++ (NSNumber *)numberWithFloat:(float)value;
++ (NSNumber *)numberWithDouble:(double)value;
++ (NSNumber *)numberWithBool:(BOOL)value;
+@end
+
+@interface NSArray
+@end
+
+@interface NSArray (NSArrayCreation)
++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
+@end
+
+@interface NSDictionary
++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
+@end
+
+#endif // OBJC_LITERAL_SUPPORT_H
diff --git a/test/CodeGenObjCXX/literals.mm b/test/CodeGenObjCXX/literals.mm
new file mode 100644
index 0000000..b8946fa
--- /dev/null
+++ b/test/CodeGenObjCXX/literals.mm
@@ -0,0 +1,111 @@
+// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -fexceptions -fobjc-exceptions -fcxx-exceptions -fobjc-arc-exceptions -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+
+#include "literal-support.h"
+
+struct X {
+  X();
+  ~X();
+  operator id() const;
+};
+
+struct Y {
+  Y();
+  ~Y();
+  operator id() const;
+};
+
+// CHECK: define void @_Z10test_arrayv
+void test_array() {
+  // CHECK: [[OBJECTS:%[a-zA-Z0-9.]+]] = alloca [2 x i8*]
+
+  // Initializing first element
+  // CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 0
+  // CHECK-NEXT: call void @_ZN1XC1Ev
+  // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv
+  // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT0]])
+  // CHECK: store i8* [[RET0]], i8** [[ELEMENT0]]
+  
+  // Initializing the second element
+  // CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1
+  // CHECK-NEXT: invoke void @_ZN1YC1Ev
+  // CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv
+  // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT1]])
+  // CHECK: store i8* [[RET1]], i8** [[ELEMENT1]]
+
+  // Build the array
+  // CHECK: {{invoke.*@objc_msgSend}}
+  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+  id arr = @[ X(), Y() ];
+
+  // Destroy temporaries
+  // CHECK-NOT: ret void
+  // CHECK: call void @objc_release
+  // CHECK-NOT: ret void
+  // CHECK: invoke void @_ZN1YD1Ev
+  // CHECK-NOT: ret void
+  // CHECK: call void @objc_release
+  // CHECK-NEXT: call void @_ZN1XD1Ev
+  // CHECK-NOT: ret void
+  // CHECK: call void @objc_release
+  // CHECK-NEXT: ret void
+
+  // Check cleanups
+  // CHECK: call void @objc_release
+  // CHECK-NOT: call void @objc_release
+  // CHECK: invoke void @_ZN1YD1Ev
+  // CHECK: call void @objc_release
+  // CHECK-NOT: call void @objc_release
+  // CHECK: invoke void @_ZN1XD1Ev
+  // CHECK-NOT: call void @objc_release
+  // CHECK: unreachable
+}
+
+// CHECK: define weak_odr void @_Z24test_array_instantiationIiEvv
+template<typename T>
+void test_array_instantiation() {
+  // CHECK: [[OBJECTS:%[a-zA-Z0-9.]+]] = alloca [2 x i8*]
+
+  // Initializing first element
+  // CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 0
+  // CHECK-NEXT: call void @_ZN1XC1Ev
+  // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv
+  // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT0]])
+  // CHECK: store i8* [[RET0]], i8** [[ELEMENT0]]
+  
+  // Initializing the second element
+  // CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1
+  // CHECK-NEXT: invoke void @_ZN1YC1Ev
+  // CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv
+  // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT1]])
+  // CHECK: store i8* [[RET1]], i8** [[ELEMENT1]]
+
+  // Build the array
+  // CHECK: {{invoke.*@objc_msgSend}}
+  // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+  id arr = @[ X(), Y() ];
+
+  // Destroy temporaries
+  // CHECK-NOT: ret void
+  // CHECK: call void @objc_release
+  // CHECK-NOT: ret void
+  // CHECK: invoke void @_ZN1YD1Ev
+  // CHECK-NOT: ret void
+  // CHECK: call void @objc_release
+  // CHECK-NEXT: call void @_ZN1XD1Ev
+  // CHECK-NOT: ret void
+  // CHECK: call void @objc_release
+  // CHECK-NEXT: ret void
+
+  // Check cleanups
+  // CHECK: call void @objc_release
+  // CHECK-NOT: call void @objc_release
+  // CHECK: invoke void @_ZN1YD1Ev
+  // CHECK: call void @objc_release
+  // CHECK-NOT: call void @objc_release
+  // CHECK: invoke void @_ZN1XD1Ev
+  // CHECK-NOT: call void @objc_release
+  // CHECK: unreachable
+}
+
+template void test_array_instantiation<int>();
+
diff --git a/test/CodeGenObjCXX/objc-container-subscripting-1.mm b/test/CodeGenObjCXX/objc-container-subscripting-1.mm
new file mode 100644
index 0000000..c0dd0f8
--- /dev/null
+++ b/test/CodeGenObjCXX/objc-container-subscripting-1.mm
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s
+
+typedef unsigned int size_t;
+@protocol P @end
+@protocol NSCopying @end
+
+@interface NSMutableArray
+- (id)objectAtIndexedSubscript:(size_t)index;
+- (void)setObject:(id)object atIndexedSubscript:(size_t)index;
+@end
+
+struct S {
+  operator unsigned int ();
+  operator id ();
+};
+
+@interface NSMutableDictionary
+- (id)objectForKeyedSubscript:(id<NSCopying>)key;
+- (void)setObject:(id)object forKeyedSubscript:(id<NSCopying>)key;
+@end
+
+int main() {
+  NSMutableArray<P> * array;
+  S s;
+  id oldObject = array[(int)s];
+
+  NSMutableDictionary<P> *dict;
+  dict[(id)s] = oldObject;
+  oldObject = dict[(id)s];
+
+}
+
+template <class T> void test2(NSMutableArray *a) {
+  a[10] = 0;
+}
+template void test2<int>(NSMutableArray*);
+// CHECK: define weak_odr void @_Z5test2IiEvP14NSMutableArray
+// CHECK: @objc_msgSend 
+// CHECK: ret void
+
+
+template <class T> void test3(NSMutableArray *a) {
+  a[sizeof(T)] = 0;
+}
+
+template void test3<int>(NSMutableArray*);
+// CHECK: define weak_odr void @_Z5test3IiEvP14NSMutableArray
+// CHECK: @objc_msgSend
+// CHECK: ret void
+
diff --git a/test/CodeGenObjCXX/objc-container-subscripting.mm b/test/CodeGenObjCXX/objc-container-subscripting.mm
new file mode 100644
index 0000000..dfe48e9
--- /dev/null
+++ b/test/CodeGenObjCXX/objc-container-subscripting.mm
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s
+
+typedef unsigned int size_t;
+@protocol P @end
+
+@interface NSMutableArray
+- (id)objectAtIndexedSubscript:(size_t)index;
+- (void)setObject:(id)object atIndexedSubscript:(size_t)index;
+@end
+
+struct S {
+  operator unsigned int ();
+  operator id ();
+};
+
+@interface NSMutableDictionary
+- (id)objectForKeyedSubscript:(id)key;
+- (void)setObject:(id)object forKeyedSubscript:(id)key;
+@end
+
+int main() {
+  NSMutableArray<P> * array;
+  S s;
+  id oldObject = array[(int)s];
+
+  NSMutableDictionary<P> *dict;
+  dict[(id)s] = oldObject;
+  oldObject = dict[(id)s];
+
+}
+
+template <class T> void test2(NSMutableArray *a) {
+  a[10] = 0;
+}
+template void test2<int>(NSMutableArray*);
+// CHECK: define weak_odr void @_Z5test2IiEvP14NSMutableArray
+// CHECK: @objc_msgSend 
+// CHECK: ret void
+
+
+template <class T> void test3(NSMutableArray *a) {
+  a[sizeof(T)] = 0;
+}
+
+template void test3<int>(NSMutableArray*);
+// CHECK: define weak_odr void @_Z5test3IiEvP14NSMutableArray
+// CHECK: @objc_msgSend
+// CHECK: ret void
+
+// CHECK: define void @_Z11static_dataP14NSMutableArray
+void static_data(NSMutableArray *array) {
+  // CHECK: call i32 @__cxa_guard_acquire
+  // CHECK: {{call i8*.*@objc_msgSend }}
+  // CHECK: call void @__cxa_guard_release
+  static id x = array[4];
+  // CHECK: ret void
+}
diff --git a/test/Driver/arclite-link.c b/test/Driver/arclite-link.c
new file mode 100644
index 0000000..9cf1efe
--- /dev/null
+++ b/test/Driver/arclite-link.c
@@ -0,0 +1,8 @@
+// RUN: touch %t.o
+// RUN: %clang -### -target x86_64-apple-darwin10 -fobjc-link-runtime -mmacosx-version-min=10.7 %t.o 2>&1 | FileCheck -check-prefix=CHECK-ARCLITE-OSX %s
+// RUN: %clang -### -target x86_64-apple-darwin10 -fobjc-link-runtime -mmacosx-version-min=10.8 %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOARCLITE %s
+// RUN: %clang -### -target i386-apple-darwin10 -fobjc-link-runtime -mmacosx-version-min=10.7 %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOARCLITE %s
+
+// CHECK-ARCLITE-OSX: libarclite_macosx.a
+// CHECK-ARCLITE-OSX: -lobjc
+// CHECK-NOARCLITE-NOT: libarclite
diff --git a/test/Driver/darwin-ld.c b/test/Driver/darwin-ld.c
index 056d347..3206f65 100644
--- a/test/Driver/darwin-ld.c
+++ b/test/Driver/darwin-ld.c
@@ -117,3 +117,7 @@
 // LINK_VERSION_MIN: "-macosx_version_min" "10.6.0"
 // LINK_VERSION_MIN: {{ld(.exe)?"}}
 // LINK_VERSION_MIN: "-macosx_version_min" "10.7.0"
+
+// RUN: %clang -target x86_64-apple-darwin12 -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_NO_CRT1 %s < %t.log
+// LINK_NO_CRT1-NOT: crt
diff --git a/test/Driver/rewrite-objc.m b/test/Driver/rewrite-objc.m
index 9e779f7..30883f3 100644
--- a/test/Driver/rewrite-objc.m
+++ b/test/Driver/rewrite-objc.m
@@ -3,7 +3,7 @@
 // TEST0: clang{{.*}}" "-cc1"
 // TEST0: "-rewrite-objc"
 // FIXME: CHECK-NOT is broken somehow, it doesn't work here. Check adjacency instead.
-// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign" "-fblocks" "-fobjc-runtime-has-arc" "-fobjc-runtime-has-weak" "-fobjc-fragile-abi" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fdiagnostics-show-option"
+// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign" "-fblocks" "-fobjc-runtime-has-arc" "-fobjc-runtime-has-weak" "-fobjc-fragile-abi" "-fobjc-default-synthesize-properties" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fdiagnostics-show-option"
 // TEST0: rewrite-objc.m"
 
 // RUN: not %clang -ccc-no-clang -target unknown -rewrite-objc %s -o - -### 2>&1 | \
diff --git a/test/PCH/objc_container.h b/test/PCH/objc_container.h
new file mode 100644
index 0000000..c83f902
--- /dev/null
+++ b/test/PCH/objc_container.h
@@ -0,0 +1,26 @@
+@protocol P @end
+
+@interface NSMutableArray
+- (id)objectAtIndexedSubscript:(unsigned int)index;
+- (void)setObject:(id)object atIndexedSubscript:(unsigned int)index;
+@end
+
+@interface NSMutableDictionary
+- (id)objectForKeyedSubscript:(id)key;
+- (void)setObject:(id)object forKeyedSubscript:(id)key;
+@end
+
+void all() {
+  NSMutableArray *array;
+  id oldObject = array[10];
+
+  array[10] = oldObject;
+
+  NSMutableDictionary *dictionary;
+  id key;
+  id newObject;
+  oldObject = dictionary[key];
+
+  dictionary[key] = newObject;
+}
+
diff --git a/test/PCH/objc_container.m b/test/PCH/objc_container.m
new file mode 100644
index 0000000..1e59054
--- /dev/null
+++ b/test/PCH/objc_container.m
@@ -0,0 +1,20 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/objc_container.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x objective-c -emit-pch -o %t %S/objc_container.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+// RUN: %clang -cc1 -include-pch %t -ast-print %s | FileCheck -check-prefix=PRINT %s
+// RUN: %clang -cc1 -include-pch %t -emit-llvm -o - %s | FileCheck -check-prefix=IR %s
+
+// CHECK-PRINT: id oldObject = array[10];
+// CHECK-PRINT: array[10] = oldObject;
+// CHECK-PRINT: oldObject = dictionary[key];
+// CHECK-PRINT: dictionary[key] = newObject;
+
+// CHECK-IR: define void @all() nounwind 
+// CHECK-IR: {{call.*objc_msgSend}}
+// CHECK-IR: {{call.*objc_msgSend}}
+// CHECK-IR: {{call.*objc_msgSend}}
+// CHECK-IR: {{call.*objc_msgSend}}
+// CHECK-IR: ret void
diff --git a/test/PCH/objc_literals.m b/test/PCH/objc_literals.m
new file mode 100644
index 0000000..cce3173
--- /dev/null
+++ b/test/PCH/objc_literals.m
@@ -0,0 +1,66 @@
+// RUN: %clang -cc1 -emit-pch -o %t %s
+// RUN: %clang -cc1 -include-pch %t -verify %s
+// RUN: %clang -cc1 -include-pch %t -ast-print %s | FileCheck -check-prefix=PRINT %s
+// RUN: %clang -cc1 -include-pch %t -emit-llvm -o - %s | FileCheck -check-prefix=IR %s
+
+#ifndef HEADER
+#define HEADER
+
+typedef unsigned char BOOL;
+
+@interface NSNumber @end
+
+@interface NSNumber (NSNumberCreation)
++ (NSNumber *)numberWithChar:(char)value;
++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
++ (NSNumber *)numberWithShort:(short)value;
++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
++ (NSNumber *)numberWithInt:(int)value;
++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
++ (NSNumber *)numberWithLong:(long)value;
++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
++ (NSNumber *)numberWithLongLong:(long long)value;
++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
++ (NSNumber *)numberWithFloat:(float)value;
++ (NSNumber *)numberWithDouble:(double)value;
++ (NSNumber *)numberWithBool:(BOOL)value;
+@end
+
+@interface NSArray
+@end
+
+@interface NSArray (NSArrayCreation)
++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
+@end
+
+@interface NSDictionary
++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
+@end
+
+// CHECK-IR: define internal void @test_numeric_literals()
+static inline void test_numeric_literals() {
+  // CHECK-PRINT: id intlit = @17
+  // CHECK-IR: {{call.*17}}
+  id intlit = @17;
+  // CHECK-PRINT: id floatlit = @17.45
+  // CHECK-IR: {{call.*1.745}}
+  id floatlit = @17.45;
+}
+
+static inline void test_array_literals() {
+  // CHECK-PRINT: id arraylit = @[ @17, @17.45
+  id arraylit = @[@17, @17.45];
+}
+
+static inline void test_dictionary_literals() {
+  // CHECK-PRINT: id dictlit = @{ @17 : {{@17.45[^,]*}}, @"hello" : @"world" };
+  id dictlit = @{@17 : @17.45, @"hello" : @"world" };
+}
+
+#else
+void test_all() {
+  test_numeric_literals();
+  test_array_literals();
+  test_dictionary_literals();
+}
+#endif
diff --git a/test/PCH/objc_literals.mm b/test/PCH/objc_literals.mm
new file mode 100644
index 0000000..8ef3351
--- /dev/null
+++ b/test/PCH/objc_literals.mm
@@ -0,0 +1,65 @@
+// RUN: %clang -cc1 -emit-pch -x objective-c++ -std=c++0x -o %t %s
+// RUN: %clang -cc1 -include-pch %t -x objective-c++ -std=c++0x  -verify %s
+// RUN: %clang -cc1 -include-pch %t -x objective-c++ -std=c++0x  -ast-print %s | FileCheck -check-prefix=PRINT %s
+// RUN: %clang -cc1 -include-pch %t -x objective-c++ -std=c++0x  -emit-llvm -o - %s | FileCheck -check-prefix=IR %s
+
+#ifndef HEADER
+#define HEADER
+
+typedef unsigned char BOOL;
+
+@interface NSNumber @end
+
+@interface NSNumber (NSNumberCreation)
++ (NSNumber *)numberWithChar:(char)value;
++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
++ (NSNumber *)numberWithShort:(short)value;
++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
++ (NSNumber *)numberWithInt:(int)value;
++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
++ (NSNumber *)numberWithLong:(long)value;
++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
++ (NSNumber *)numberWithLongLong:(long long)value;
++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
++ (NSNumber *)numberWithFloat:(float)value;
++ (NSNumber *)numberWithDouble:(double)value;
++ (NSNumber *)numberWithBool:(BOOL)value;
+@end
+
+@interface NSArray
+@end
+
+@interface NSArray (NSArrayCreation)
++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
+@end
+
+@interface NSDictionary
++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
+@end
+
+template<typename T, typename U>
+struct pair {
+  T first;
+  U second;
+};
+
+template<typename T, typename U>
+pair<T, U> make_pair(const T& first, const U& second) {
+  return { first, second };
+}
+
+// CHECK-IR: define linkonce_odr void @_Z29variadic_dictionary_expansionIJP8NSStringS1_EJP8NSNumberS3_EEvDp4pairIT_T0_E
+template<typename ...Ts, typename ... Us>
+void variadic_dictionary_expansion(pair<Ts, Us>... key_values) {
+  // CHECK-PRINT: id dict = @{ key_values.first : key_values.second... };
+  // CHECK-IR: {{call.*objc_msgSend}}
+  // CHECK-IR: ret void
+  id dict = @{ key_values.first : key_values.second ... };
+}
+
+#else
+void test_all() {
+  variadic_dictionary_expansion(make_pair(@"Seventeen", @17), 
+                                make_pair(@"YES", @true));
+}
+#endif
diff --git a/test/PCH/subscripting-literals.m b/test/PCH/subscripting-literals.m
new file mode 100644
index 0000000..1675373
--- /dev/null
+++ b/test/PCH/subscripting-literals.m
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o %t.nopch.ll %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-pch -o %t.pch %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o %t.pch.ll %s -include-pch %t.pch
+// RUN: diff %t.nopch.ll %t.pch.ll
+
+#ifndef HEADER
+#define HEADER
+
+@interface NSArray
+- (id)objectAtIndexedSubscript:(int)index;
++ (id)arrayWithObjects:(id *)objects count:(unsigned)count;
+@end
+
+@interface NSMutableArray : NSArray
+- (void)setObject:(id)object atIndexedSubscript:(int)index;
+@end
+
+@interface NSDictionary
+- (id)objectForKeyedSubscript:(id)key;
++ (id)dictionaryWithObjects:(id *)objects forKeys:(id *)keys count:(unsigned)count;
+@end
+
+@interface NSMutableDictionary : NSDictionary
+- (void)setObject:(id)object forKeyedSubscript:(id)key;
+@end
+
+@interface NSNumber
++ (NSNumber *)numberWithInt:(int)value;
+@end
+
+@class NSString;
+
+id testArray(int idx, id p) {
+  NSMutableArray *array;
+  array[idx] = p;
+  NSArray *arr = @[ p, @7 ];
+  return array[idx];
+}
+
+void testDict(NSString *key, id newObject, id oldObject) {
+  NSMutableDictionary *dictionary;
+  oldObject = dictionary[key];
+  dictionary[key] = newObject;
+  NSDictionary *dict = @{ key: newObject, key: oldObject };
+}
+
+#endif
diff --git a/test/SemaObjC/cocoa-api-usage.m b/test/SemaObjC/cocoa-api-usage.m
new file mode 100644
index 0000000..85e2115
--- /dev/null
+++ b/test/SemaObjC/cocoa-api-usage.m
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -fsyntax-only -Wobjc-cocoa-api -verify
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %s -fsyntax-only -Wobjc-cocoa-api -verify
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c %s.fixed -fsyntax-only
+// RUN: cp %s %t.m
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %t.m -fixit -Wobjc-cocoa-api
+// RUN: diff %s.fixed %t.m
+// RUN: cp %s %t.m
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %t.m -fixit -Wobjc-cocoa-api
+// RUN: diff %s.fixed %t.m
+
+typedef signed char BOOL;
+#define nil ((void*) 0)
+
+@interface NSObject
++ (id)alloc;
+@end
+
+@interface NSString : NSObject
++ (id)stringWithString:(NSString *)string;
+- (id)initWithString:(NSString *)aString;
+@end
+
+@interface NSArray : NSObject
+- (id)objectAtIndex:(unsigned long)index;
+- (id)objectAtIndexedSubscript:(int)index;
+@end
+
+@interface NSArray (NSArrayCreation)
++ (id)array;
++ (id)arrayWithObject:(id)anObject;
++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
++ (id)arrayWithObjects:(id)firstObj, ...;
++ (id)arrayWithArray:(NSArray *)array;
+
+- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt;
+- (id)initWithObjects:(id)firstObj, ...;
+- (id)initWithArray:(NSArray *)array;
+
+- (id)objectAtIndex:(unsigned long)index;
+@end
+
+@interface NSMutableArray : NSArray
+- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject;
+- (void)setObject:(id)object atIndexedSubscript:(int)index;
+@end
+
+@interface NSDictionary : NSObject
+- (id)objectForKeyedSubscript:(id)key;
+@end
+
+@interface NSDictionary (NSDictionaryCreation)
++ (id)dictionary;
++ (id)dictionaryWithObject:(id)object forKey:(id)key;
++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
++ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...;
++ (id)dictionaryWithDictionary:(NSDictionary *)dict;
++ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;
+
+- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
+- (id)initWithObjectsAndKeys:(id)firstObject, ...;
+- (id)initWithDictionary:(NSDictionary *)otherDictionary;
+- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;
+
+- (id)objectForKey:(id)aKey;
+@end
+
+@interface NSMutableDictionary : NSDictionary
+- (void)setObject:(id)anObject forKey:(id)aKey;
+- (void)setObject:(id)object forKeyedSubscript:(id)key;
+@end
+
+@interface NSNumber : NSObject
+@end
+
+@interface NSNumber (NSNumberCreation)
++ (NSNumber *)numberWithInt:(int)value;
+@end
+
+#define M(x) (x)
+#define PAIR(x) @#x, [NSNumber numberWithInt:(x)]
+#define TWO(x) ((x), (x))
+
+void foo() {
+  NSString *str = M([NSString stringWithString:@"foo"]); // expected-warning {{redundant}}
+  str = [[NSString alloc] initWithString:@"foo"];
+  NSArray *arr = [NSArray arrayWithArray:@[str]]; // expected-warning {{redundant}}
+  NSDictionary *dict = [NSDictionary dictionaryWithDictionary:@{str: arr}]; // expected-warning {{redundant}}
+}
diff --git a/test/SemaObjC/cocoa-api-usage.m.fixed b/test/SemaObjC/cocoa-api-usage.m.fixed
new file mode 100644
index 0000000..55e060a
--- /dev/null
+++ b/test/SemaObjC/cocoa-api-usage.m.fixed
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -fsyntax-only -Wobjc-cocoa-api -verify
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %s -fsyntax-only -Wobjc-cocoa-api -verify
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c %s.fixed -fsyntax-only
+// RUN: cp %s %t.m
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %t.m -fixit -Wobjc-cocoa-api
+// RUN: diff %s.fixed %t.m
+// RUN: cp %s %t.m
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %t.m -fixit -Wobjc-cocoa-api
+// RUN: diff %s.fixed %t.m
+
+typedef signed char BOOL;
+#define nil ((void*) 0)
+
+@interface NSObject
++ (id)alloc;
+@end
+
+@interface NSString : NSObject
++ (id)stringWithString:(NSString *)string;
+- (id)initWithString:(NSString *)aString;
+@end
+
+@interface NSArray : NSObject
+- (id)objectAtIndex:(unsigned long)index;
+- (id)objectAtIndexedSubscript:(int)index;
+@end
+
+@interface NSArray (NSArrayCreation)
++ (id)array;
++ (id)arrayWithObject:(id)anObject;
++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
++ (id)arrayWithObjects:(id)firstObj, ...;
++ (id)arrayWithArray:(NSArray *)array;
+
+- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt;
+- (id)initWithObjects:(id)firstObj, ...;
+- (id)initWithArray:(NSArray *)array;
+
+- (id)objectAtIndex:(unsigned long)index;
+@end
+
+@interface NSMutableArray : NSArray
+- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject;
+- (void)setObject:(id)object atIndexedSubscript:(int)index;
+@end
+
+@interface NSDictionary : NSObject
+- (id)objectForKeyedSubscript:(id)key;
+@end
+
+@interface NSDictionary (NSDictionaryCreation)
++ (id)dictionary;
++ (id)dictionaryWithObject:(id)object forKey:(id)key;
++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
++ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...;
++ (id)dictionaryWithDictionary:(NSDictionary *)dict;
++ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;
+
+- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
+- (id)initWithObjectsAndKeys:(id)firstObject, ...;
+- (id)initWithDictionary:(NSDictionary *)otherDictionary;
+- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;
+
+- (id)objectForKey:(id)aKey;
+@end
+
+@interface NSMutableDictionary : NSDictionary
+- (void)setObject:(id)anObject forKey:(id)aKey;
+- (void)setObject:(id)object forKeyedSubscript:(id)key;
+@end
+
+@interface NSNumber : NSObject
+@end
+
+@interface NSNumber (NSNumberCreation)
++ (NSNumber *)numberWithInt:(int)value;
+@end
+
+#define M(x) (x)
+#define PAIR(x) @#x, [NSNumber numberWithInt:(x)]
+#define TWO(x) ((x), (x))
+
+void foo() {
+  NSString *str = M(@"foo"); // expected-warning {{redundant}}
+  str = [[NSString alloc] initWithString:@"foo"];
+  NSArray *arr = @[str]; // expected-warning {{redundant}}
+  NSDictionary *dict = @{str: arr}; // expected-warning {{redundant}}
+}
diff --git a/test/SemaObjC/invalid-code.m b/test/SemaObjC/invalid-code.m
index 8378ed7..7b65912 100644
--- a/test/SemaObjC/invalid-code.m
+++ b/test/SemaObjC/invalid-code.m
@@ -2,7 +2,8 @@
 
 // rdar://6124613
 void test1() {
-  void *p = @1; // expected-error {{unexpected '@' in program}}
+  void *xyzzy = 0;
+  void *p = @xyzzy; // expected-error {{unexpected '@' in program}}
 }
 
 // <rdar://problem/7495713>
diff --git a/test/SemaObjC/objc-array-literal.m b/test/SemaObjC/objc-array-literal.m
new file mode 100644
index 0000000..9f59316
--- /dev/null
+++ b/test/SemaObjC/objc-array-literal.m
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+// rdar://10111397
+
+#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
+typedef unsigned long NSUInteger;
+#else
+typedef unsigned int NSUInteger;
+#endif
+
+@class NSString;
+
+extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
+
+@class NSFastEnumerationState;
+
+@protocol NSFastEnumeration
+
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id [])buffer count:(NSUInteger)len;
+
+@end
+
+@interface NSNumber 
++ (NSNumber *)numberWithInt:(int)value;
+@end
+
+@interface NSArray <NSFastEnumeration>
++ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
+@end
+
+
+int main() {
+ NSArray *array = @[@"Hello", @"There", @"How Are You", [NSNumber numberWithInt:42]];
+
+  for (id string in array)
+    NSLog(@"%@\n", string);
+
+  NSArray *array1 = @["Forgot"]; // expected-error {{string literal must be prefixed by '@' in a collection}}
+
+  const char *blah;
+  NSArray *array2 = @[blah]; // expected-error{{collection element of type 'const char *' is not an Objective-C object}}
+}
diff --git a/test/SemaObjC/objc-container-subscripting-1.m b/test/SemaObjC/objc-container-subscripting-1.m
new file mode 100644
index 0000000..a58a7c3
--- /dev/null
+++ b/test/SemaObjC/objc-container-subscripting-1.m
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+typedef unsigned int size_t;
+@protocol P @end
+
+@interface NSMutableArray
+@end
+
+@interface XNSMutableArray
+@end
+
+int main() {
+id array;
+id oldObject = array[10]; // expected-warning {{instance method '-objectAtIndexedSubscript:' not found (return type defaults to 'id')}}
+
+array[10] = 0; // expected-warning {{instance method '-setObject:atIndexedSubscript:' not found (return type defaults to 'id')}}
+
+id<P> p_array;
+oldObject = p_array[10]; // expected-warning {{instance method '-objectAtIndexedSubscript:' not found (return type defaults to 'id')}}
+
+p_array[10] = 0; // expected-warning {{instance method '-setObject:atIndexedSubscript:' not found (return type defaults to 'id')}}
+}
+
diff --git a/test/SemaObjC/objc-container-subscripting-2.m b/test/SemaObjC/objc-container-subscripting-2.m
new file mode 100644
index 0000000..2564975
--- /dev/null
+++ b/test/SemaObjC/objc-container-subscripting-2.m
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+typedef unsigned int size_t;
+@protocol P @end
+
+@interface NSMutableArray
+- (id)objectAtIndexedSubscript:(size_t)index;
+- (void)setObject:(id)object atIndexedSubscript:(size_t)index;
+@end
+
+@interface NSMutableDictionary
+- (id)objectForKeyedSubscript:(id)key;
+- (void)setObject:(id)object forKeyedSubscript:(size_t)key;
+@end
+
+id func() {
+  NSMutableArray *array;
+  float f; 
+  array[f] = array; // expected-error {{expected method to write dictionary element not found on object of type 'NSMutableArray *'}}
+  return array[3.14]; // expected-error {{expected method to read dictionary element not found on object of type 'NSMutableArray *'}}
+}
+
+void test_unused() {
+  NSMutableArray *array;
+  array[10]; // expected-warning {{container access result unused - container access should not be used for side effects}} 
+
+  NSMutableDictionary *dict;
+  dict[array]; // expected-warning {{container access result unused - container access should not be used for side effects}}
+}
+
diff --git a/test/SemaObjC/objc-container-subscripting-3.m b/test/SemaObjC/objc-container-subscripting-3.m
new file mode 100644
index 0000000..5fd1a10
--- /dev/null
+++ b/test/SemaObjC/objc-container-subscripting-3.m
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+// rdar://10904488
+
+@interface Test
+- (int)objectAtIndexedSubscript:(int)index; // expected-note {{method 'objectAtIndexedSubscript:' declared here}}
+- (void)setObject:(int)object atIndexedSubscript:(int)index; // expected-note {{parameter of type 'int' is declared here}}
+@end
+
+@interface NSMutableDictionary
+- (int)objectForKeyedSubscript:(id)key; // expected-note {{method 'objectForKeyedSubscript:' declared here}}
+- (void)setObject:(int)object forKeyedSubscript:(id)key; // expected-note {{parameter of type 'int' is declared here}}
+@end
+
+int main() {
+   Test *array;
+   int i = array[10]; // expected-error {{method for accessing array element must have Objective-C object return type instead of 'int'}}
+   array[2] = i;     // expected-error {{cannot assign to this array because assigning method's 2nd parameter of type 'int' is not an objective-C pointer type}}
+
+   NSMutableDictionary *dict;
+   id key, val;
+   val = dict[key]; // expected-error {{method for accessing dictionary element must have Objective-C object return type instead of 'int'}} \
+                    // expected-warning {{incompatible integer to pointer conversion assigning to 'id' from 'int'}}
+   dict[key] = val; // expected-error {{method object parameter type 'int' is not object type}}
+}
+
diff --git a/test/SemaObjC/objc-container-subscripting.m b/test/SemaObjC/objc-container-subscripting.m
new file mode 100644
index 0000000..4125bc6
--- /dev/null
+++ b/test/SemaObjC/objc-container-subscripting.m
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
+typedef unsigned int size_t;
+@protocol P @end
+
+@interface NSMutableArray
+- (id)objectAtIndexedSubscript:(double)index; // expected-note {{parameter of type 'double' is declared here}}
+- (void)setObject:(id *)object atIndexedSubscript:(void *)index; // expected-note {{parameter of type 'void *' is declared here}} \
+								 // expected-note {{parameter of type 'id *' is declared here}}
+@end
+@interface I @end
+
+int main() {
+  NSMutableArray<P> * array;
+  id  oldObject = array[10]; // expected-error {{method index parameter type 'double' is not integral type}}
+  array[3] = 0; // expected-error {{method index parameter type 'void *' is not integral type}} \
+                // expected-error {{cannot assign to this array because assigning method's 2nd parameter of type 'id *' is not an objective-C pointer type}}
+
+  I* iarray;
+  iarray[3] = 0; // expected-error {{expected method to write array element not found on object of type 'I *'}}
+  I* p = iarray[4]; // expected-error {{expected method to read array element not found on object of type 'I *'}}
+
+  oldObject = array[10]++; // expected-error {{illegal operation on objective-c container subscripting}}
+  oldObject = array[10]--; // expected-error {{illegal operation on objective-c container subscripting}}
+  oldObject = --array[10]; // expected-error {{illegal operation on objective-c container subscripting}}
+}
+
+@interface NSMutableDictionary
+- (id)objectForKeyedSubscript:(id*)key; // expected-note {{parameter of type 'id *' is declared here}}
+- (void)setObject:(void*)object forKeyedSubscript:(id*)key; // expected-note {{parameter of type 'void *' is declared here}} \
+                                                            // expected-note {{parameter of type 'id *' is declared here}}
+@end
+@class NSString;
+
+void testDict() {
+  NSMutableDictionary *dictionary;
+  NSString *key;
+  id newObject, oldObject;
+  oldObject = dictionary[key];  // expected-error {{method key parameter type 'id *' is not object type}}
+  dictionary[key] = newObject;  // expected-error {{method object parameter type 'void *' is not object type}} \
+                                // expected-error {{method key parameter type 'id *' is not object type}}
+}
diff --git a/test/SemaObjC/objc-literal-nsnumber.m b/test/SemaObjC/objc-literal-nsnumber.m
new file mode 100644
index 0000000..db6183e
--- /dev/null
+++ b/test/SemaObjC/objc-literal-nsnumber.m
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1  -fsyntax-only -fblocks -verify %s
+// rdar://10111397
+
+#if __LP64__
+typedef unsigned long NSUInteger;
+#else
+typedef unsigned int NSUInteger;
+#endif
+
+@interface NSObject
++ (NSObject*)nsobject;
+@end
+
+@interface NSNumber : NSObject
++ (NSNumber *)numberWithChar:(char)value;
++ (NSNumber *)numberWithInt:(int)value;
++ (NSNumber *)numberWithFloat:(float)value;
+@end
+
+int main() {
+  NSNumber * N = @3.1415926535;  // expected-error {{declaration of 'numberWithDouble:' is missing in NSNumber class}}
+  NSNumber *noNumber = @__objc_yes; // expected-error {{declaration of 'numberWithBool:' is missing in NSNumber class}}
+  NSNumber * NInt = @1000;
+  NSNumber * NLongDouble = @1000.0l; // expected-error{{'long double' is not a valid literal type for NSNumber}}
+  id character = @ 'a';
+
+  NSNumber *NNegativeInt = @-1000;
+  NSNumber *NPositiveInt = @+1000;
+  NSNumber *NNegativeFloat = @-1000.1f;
+  NSNumber *NPositiveFloat = @+1000.1f;
+
+  int five = 5;
+  @-five; // expected-error{{@- must be followed by a number to form an NSNumber object}}
+  @+five; // expected-error{{@+ must be followed by a number to form an NSNumber object}}
+}
+
+// Dictionary test
+@class NSDictionary;
+
+NSDictionary *err() {
+  return @{@"name" : @"value"}; // expected-error {{declaration of 'dictionaryWithObjects:forKeys:count:' is missing in NSDictionary class}}
+}
+
+@interface NSDate : NSObject
++ (NSDate *) date;
+@end
+
+@protocol NSCopying
+- copy;
+@end
+
+@interface NSDictionary : NSObject
++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(NSUInteger)cnt;
+@end
+
+@interface NSString<NSCopying>
+@end
+
+id NSUserName();
+
+int Int();
+
+NSDictionary * blocks() {
+  return @{ @"task" : ^ { return 17; } };
+}
+
+NSDictionary * warn() {
+  NSDictionary *dictionary = @{@"name" : NSUserName(),
+                               @"date" : [NSDate date],
+                               @"name2" : @"other",
+                               NSObject.nsobject : @"nsobject" }; // expected-warning{{passing 'NSObject *' to parameter of incompatible type 'const id<NSCopying>'}}
+  NSDictionary *dictionary2 = @{@"name" : Int()}; // expected-error {{collection element of type 'int' is not an Objective-C object}}
+
+  NSObject *o;
+  NSDictionary *dictionary3 = @{o : o, // expected-warning{{passing 'NSObject *' to parameter of incompatible type 'const id<NSCopying>'}}
+                               @"date" : [NSDate date] };
+  return dictionary3;
+}
diff --git a/test/SemaObjC/objc-literal-sig.m b/test/SemaObjC/objc-literal-sig.m
new file mode 100644
index 0000000..fb5c79f
--- /dev/null
+++ b/test/SemaObjC/objc-literal-sig.m
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+typedef _Bool BOOL;
+
+@interface NSNumber @end
+
+@interface NSNumber (NSNumberCreation)
++ (NSNumber *)numberWithChar:(char)value;
++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
++ (NSNumber *)numberWithShort:(short)value;
++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
++ (NSNumber *)numberWithInt:(int)value;
++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
++ (NSNumber *)numberWithLong:(long)value;
++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
++ (NSNumber *)numberWithLongLong:(long long)value;
++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
++ (NSNumber *)numberWithFloat:(float)value;
++ (NSNumber *)numberWithDouble:(double)value;
++ (int)numberWithBool:(BOOL)value; // expected-note{{method returns unexpected type 'int' (should be an object type)}}
+@end
+
+@interface NSArray
+@end
+
+@interface NSArray (NSArrayCreation)
++ (id)arrayWithObjects:(const int [])objects // expected-note{{first parameter has unexpected type 'const int *' (should be 'const id *')}}
+                 count:(unsigned long)cnt;
+@end
+
+@interface NSDictionary
++ (id)dictionaryWithObjects:(const id [])objects
+                    forKeys:(const int [])keys // expected-note{{second parameter has unexpected type 'const int *' (should be 'const id *')}}
+                      count:(unsigned long)cnt;
+@end
+
+void test_sig() {
+  (void)@__objc_yes; // expected-error{{literal construction method 'numberWithBool:' has incompatible signature}}
+  id array = @[ @17 ]; // expected-error{{literal construction method 'arrayWithObjects:count:' has incompatible signature}}
+  id dict = @{ @"hello" : @17 }; // expected-error{{literal construction method 'dictionaryWithObjects:forKeys:count:' has incompatible signature}}
+}
diff --git a/test/SemaObjC/sizeof-interface.m b/test/SemaObjC/sizeof-interface.m
index dd8c1fd..dc99bef 100644
--- a/test/SemaObjC/sizeof-interface.m
+++ b/test/SemaObjC/sizeof-interface.m
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -verify -fsyntax-only %s
 
-@class I0; // expected-note 3{{forward declaration of class here}}
+@class I0; // expected-note 2{{forward declaration of class here}}
 
 // rdar://6811884
 int g0 = sizeof(I0); // expected-error{{invalid application of 'sizeof' to an incomplete type 'I0'}}
@@ -9,7 +9,7 @@
 void *g3(I0 *P) {
   P = P+5;        // expected-error {{arithmetic on a pointer to an incomplete type 'I0'}}
 
-  return &P[4];   // expected-error{{subscript of pointer to incomplete type 'I0'}}
+  return &P[4];   // expected-error{{expected method to read array element not found on object of type 'I0 *'}}
 }
 
 
@@ -55,7 +55,7 @@
   P = 5+P;  // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}}
   P = P-5;  // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}}
   
-  return P[4].x[2];  // expected-error {{subscript requires size of interface 'I0', which is not constant in non-fragile ABI}}
+  return P[4].x[2];  // expected-error {{expected method to read array element not found on object of type 'I0 *'}}
 }
 
 
diff --git a/test/SemaObjCXX/literals.mm b/test/SemaObjCXX/literals.mm
new file mode 100644
index 0000000..1f6782a
--- /dev/null
+++ b/test/SemaObjCXX/literals.mm
@@ -0,0 +1,178 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x -fblocks %s
+
+typedef unsigned char BOOL;
+
+@protocol NSCopying
+- copy;
+@end
+
+@interface NSObject
+@end
+
+@interface NSNumber : NSObject <NSCopying>
+-copy;
+@end
+
+@interface NSNumber (NSNumberCreation)
++ (NSNumber *)numberWithChar:(char)value;
++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
++ (NSNumber *)numberWithShort:(short)value;
++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
++ (NSNumber *)numberWithInt:(int)value;
++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
++ (NSNumber *)numberWithLong:(long)value;
++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
++ (NSNumber *)numberWithLongLong:(long long)value;
++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
++ (NSNumber *)numberWithFloat:(float)value;
++ (NSNumber *)numberWithDouble:(double)value;
++ (NSNumber *)numberWithBool:(BOOL)value;
+@end
+
+@interface NSArray : NSObject <NSCopying>
+-copy;
+@end
+
+@interface NSArray (NSArrayCreation)
++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
+@end
+
+@interface NSDictionary
++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(unsigned long)cnt;
+@end
+
+template<typename T>
+struct ConvertibleTo {
+  operator T();
+};
+
+template<typename T>
+struct ExplicitlyConvertibleTo {
+  explicit operator T();
+};
+
+template<typename T>
+class PrivateConvertibleTo {
+private:
+  operator T(); // expected-note{{declared private here}}
+};
+
+template<typename T> ConvertibleTo<T> makeConvertible();
+
+struct X {
+  ConvertibleTo<id> x;
+  ConvertibleTo<id> get();
+};
+
+template<typename T> T test_numeric_instantiation() {
+  return @-17.42;
+}
+
+template id test_numeric_instantiation();
+
+void test_convertibility(ConvertibleTo<NSArray*> toArray,
+                         ConvertibleTo<id> toId,
+                         ConvertibleTo<int (^)(int)> toBlock,
+                         ConvertibleTo<int> toInt,
+                         ExplicitlyConvertibleTo<NSArray *> toArrayExplicit) {
+  id array = @[ 
+               toArray,
+               toId,
+               toBlock,
+               toInt // expected-error{{collection element of type 'ConvertibleTo<int>' is not an Objective-C object}}
+              ];
+  id array2 = @[ toArrayExplicit ]; // expected-error{{collection element of type 'ExplicitlyConvertibleTo<NSArray *>' is not an Objective-C object}}
+
+  id array3 = @[ 
+                makeConvertible<id>(),
+                               makeConvertible<id>, // expected-error{{collection element of type 'ConvertibleTo<id> ()' is not an Objective-C object}}
+               ];
+
+  X x;
+  id array4 = @[ x.x ];
+  id array5 = @[ x.get ]; // expected-error{{reference to non-static member function must be called}}
+  id array6 = @[ PrivateConvertibleTo<NSArray*>() ]; // expected-error{{operator NSArray *' is a private member of 'PrivateConvertibleTo<NSArray *>'}}
+}
+
+template<typename T>
+void test_array_literals(T t) {
+  id arr = @[ @17, t ]; // expected-error{{collection element of type 'int' is not an Objective-C object}}
+}
+
+template void test_array_literals(id);
+template void test_array_literals(NSArray*);
+template void test_array_literals(int); // expected-note{{in instantiation of function template specialization 'test_array_literals<int>' requested here}}
+
+template<typename T, typename U>
+void test_dictionary_literals(T t, U u) {
+  NSObject *object;
+  id dict = @{ 
+    @17 : t, // expected-error{{collection element of type 'int' is not an Objective-C object}}
+    u : @42 // expected-error{{collection element of type 'int' is not an Objective-C object}}
+  };
+
+  id dict2 = @{ 
+    object : @"object" // expected-error{{cannot initialize a parameter of type 'const id<NSCopying>' with an rvalue of type 'NSObject *'}}
+  }; 
+}
+
+template void test_dictionary_literals(id, NSArray*);
+template void test_dictionary_literals(NSArray*, id);
+template void test_dictionary_literals(int, id); // expected-note{{in instantiation of function template specialization 'test_dictionary_literals<int, id>' requested here}}
+template void test_dictionary_literals(id, int); // expected-note{{in instantiation of function template specialization 'test_dictionary_literals<id, int>' requested here}}
+
+template<typename ...Args>
+void test_bad_variadic_array_literal(Args ...args) {
+  id arr1 = @[ args ]; // expected-error{{initializer contains unexpanded parameter pack 'args'}}
+}
+
+template<typename ...Args>
+void test_variadic_array_literal(Args ...args) {
+  id arr1 = @[ args... ]; // expected-error{{collection element of type 'int' is not an Objective-C object}}
+}
+template void test_variadic_array_literal(id);
+template void test_variadic_array_literal(id, NSArray*);
+template void test_variadic_array_literal(id, int, NSArray*); // expected-note{{in instantiation of function template specialization 'test_variadic_array_literal<id, int, NSArray *>' requested here}}
+
+template<typename ...Args>
+void test_bad_variadic_dictionary_literal(Args ...args) {
+  id dict = @{ args : @17 }; // expected-error{{initializer contains unexpanded parameter pack 'args'}}
+}
+
+// Test array literal pack expansions. 
+template<typename T, typename U>
+struct pair {
+  T first;
+  U second;
+};
+
+template<typename T, typename ...Ts, typename ... Us>
+void test_variadic_dictionary_expansion(T t, pair<Ts, Us>... key_values) {
+  id dict = @{ 
+    t : key_values.second ..., // expected-error{{collection element of type 'int' is not an Objective-C object}}
+    key_values.first : key_values.second ..., // expected-error{{collection element of type 'float' is not an Objective-C object}}
+    key_values.second : t ...
+  };
+}
+
+template void test_variadic_dictionary_expansion(id, 
+                                                 pair<NSNumber*, id>,
+                                                 pair<id, ConvertibleTo<id>>);
+template void test_variadic_dictionary_expansion(NSNumber *, // expected-note{{in instantiation of function template specialization}}
+                                                 pair<NSNumber*, int>,
+                                                 pair<id, ConvertibleTo<id>>);
+template void test_variadic_dictionary_expansion(NSNumber *, // expected-note{{in instantiation of function template specialization}}
+                                                 pair<NSNumber*, id>,
+                                                 pair<float, ConvertibleTo<id>>);
+
+// Test parsing 
+struct key {
+  static id value;
+};
+
+id key;
+id value;
+
+void test_dictionary_colon() {
+  id dict = @{ key : value };
+}
diff --git a/test/SemaObjCXX/objc-container-subscripting.mm b/test/SemaObjCXX/objc-container-subscripting.mm
new file mode 100644
index 0000000..ccbc45e
--- /dev/null
+++ b/test/SemaObjCXX/objc-container-subscripting.mm
@@ -0,0 +1,138 @@
+// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin11 -fsyntax-only -std=c++11 -verify %s
+
+@class NSArray;
+
+@interface NSMutableDictionary
+- (id)objectForKeyedSubscript:(id)key;
+- (void)setObject:(id)object forKeyedSubscript:(id)key; // expected-note {{passing argument to parameter 'object' here}}
+@end
+
+template<typename T, typename U, typename O>
+void test_dictionary_subscripts(T base, U key, O obj) {
+  base[key] = obj; // expected-error {{expected method to write array element not found on object of type 'NSMutableDictionary *'}} \
+                   // expected-error {{cannot initialize a parameter of type 'id' with an lvalue of type 'int'}}
+  obj = base[key];  // expected-error {{expected method to read array element not found on object of type 'NSMutableDictionary *'}} \
+                    // expected-error {{assigning to 'int' from incompatible type 'id'}}
+     
+}
+
+template void test_dictionary_subscripts(NSMutableDictionary*, id, NSArray *ns);
+
+template void test_dictionary_subscripts(NSMutableDictionary*, NSArray *ns, id);
+
+template void test_dictionary_subscripts(NSMutableDictionary*, int, id); // expected-note {{in instantiation of function template specialization 'test_dictionary_subscripts<NSMutableDictionary *, int, id>' requested here}}
+
+template void test_dictionary_subscripts(NSMutableDictionary*, id, int); // expected-note {{in instantiation of function template specialization 'test_dictionary_subscripts<NSMutableDictionary *, id, int>' requested here}}
+
+
+@interface NSMutableArray
+- (id)objectAtIndexedSubscript:(int)index;
+- (void)setObject:(id)object atIndexedSubscript:(int)index;
+@end
+
+template<typename T, typename U, typename O>
+void test_array_subscripts(T base, U index, O obj) {
+  base[index] = obj; // expected-error {{expected method to write dictionary element not found on object of type 'NSMutableArray *'}}
+  obj = base[index]; // expected-error {{expected method to read dictionary element not found on object of type 'NSMutableArray *'}}
+}
+
+template void  test_array_subscripts(NSMutableArray *, int, id);
+template void  test_array_subscripts(NSMutableArray *, short, id);
+enum E { e };
+
+template void  test_array_subscripts(NSMutableArray *, E, id);
+
+template void  test_array_subscripts(NSMutableArray *, double, id); // expected-note {{in instantiation of function template specialization 'test_array_subscripts<NSMutableArray *, double, id>' requested here}}
+
+template<typename T>
+struct ConvertibleTo {
+  operator T();
+};
+
+template<typename T>
+struct ExplicitlyConvertibleTo {
+  explicit operator T();
+};
+
+template<typename T> ConvertibleTo<T> makeConvertible();
+
+struct X {
+  ConvertibleTo<id> x;
+  ConvertibleTo<id> get();
+};
+
+NSMutableArray *test_array_convertibility(ConvertibleTo<NSMutableArray*> toArray,
+                         ConvertibleTo<id> toId,
+                         ConvertibleTo<int (^)(int)> toBlock,
+                         ConvertibleTo<int> toInt,
+                         ExplicitlyConvertibleTo<NSMutableArray *> toArrayExplicit) {
+  id array;
+
+  array[1] = toArray;
+
+  array[4] = array[1];
+ 
+  toArrayExplicit[2] = toId; // expected-error {{type 'ExplicitlyConvertibleTo<NSMutableArray *>' does not provide a subscript operator}}
+
+  return array[toInt];
+  
+}
+
+id test_dict_convertibility(ConvertibleTo<NSMutableDictionary*> toDict,
+                         ConvertibleTo<id> toId,
+                         ConvertibleTo<int (^)(int)> toBlock,
+                         ConvertibleTo<int> toInt,
+                         ExplicitlyConvertibleTo<NSMutableDictionary *> toDictExplicit) {
+
+
+  NSMutableDictionary *Dict;
+  id Id;
+  Dict[toId] = toBlock;
+
+  Dict[toBlock] = toBlock;
+
+  Dict[toBlock] = Dict[toId] = Dict[toBlock];
+
+  Id = toDictExplicit[toId] = Id; // expected-error {{no viable overloaded operator[] for type 'ExplicitlyConvertibleTo<NSMutableDictionary *>'}}
+
+  return Dict[toBlock];
+}
+
+
+template<typename ...Args>
+void test_bad_variadic_array_subscripting(Args ...args) {
+  id arr1;
+  arr1[3] = args; // expected-error {{expression contains unexpanded parameter pack 'args'}}
+}
+
+template<typename ...Args>
+void test_variadic_array_subscripting(Args ...args) {
+  id arr[] = {args[3]...}; // which means: {a[3], b[3], c[3]};
+}
+
+template void test_variadic_array_subscripting(id arg1, NSMutableArray* arg2, id arg3);
+
+@class Key;
+
+template<typename Index, typename ...Args>
+void test_variadic_dictionary_subscripting(Index I, Args ...args) {
+  id arr[] = {args[I]...}; // which means: {a[3], b[3], c[3]};
+}
+
+template void test_variadic_dictionary_subscripting(Key *key, id arg1, NSMutableDictionary* arg2, id arg3);
+
+template<int N>
+id get(NSMutableArray *array) {
+ return array[N]; // array[N] should be a value- and instantiation-dependent ObjCSubscriptRefExpr
+}
+
+struct WeirdIndex {
+   operator int(); // expected-note {{type conversion function declared here}}
+   operator id(); // expected-note {{type conversion function declared here}}
+};
+
+id FUNC(WeirdIndex w) {
+  NSMutableArray *array;
+  return array[w]; // expected-error {{indexing expression is invalid because subscript type 'WeirdIndex' has multiple type conversion functions}}
+}
+