blob: c679c2391c3811b903aa5f301bd1966f61b0b2cc [file] [edit]
// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-macosx11.0.0 -fobjc-runtime=macosx-11.0.0 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -fobjc-constant-literals -fconstant-nsnumber-literals -fconstant-nsarray-literals -fconstant-nsdictionary-literals -O2 -disable-llvm-passes -o - %s | FileCheck %s
#include "literal-support.h"
#if __has_feature(objc_constant_literals)
#if __has_feature(objc_bool)
#define YES __objc_yes
#define NO __objc_no
#else
#define YES ((BOOL)1)
#define NO ((BOOL)0)
#endif
// Check that the constant classes were picked and emitted
// CHECK: %struct.__builtin_NSDictionary = type { ptr, i64, i64, ptr, ptr }
// CHECK: %struct.__builtin_NSConstantIntegerNumber = type { ptr, ptr, i64 }
// CHECK: %struct.__builtin_NSArray = type { ptr, i64, ptr }
// CHECK: %struct.__builtin_NSConstantDoubleNumber = type { ptr, double }
// CHECK: %struct.__builtin_NSConstantFloatNumber = type { ptr, float }
// Ensure we're able to use literals at global scope
// CHECK: @"OBJC_CLASS_$_NSConstantDictionary" = external global %struct._class_t
// CHECK: @_unnamed_array_storage = internal unnamed_addr constant [1 x ptr] [ptr @_unnamed_cfstring_], section "__DATA,__objc_arraydata,regular,no_dead_strip", align 8
// CHECK: @_unnamed_array_storage.3 = internal unnamed_addr constant [1 x ptr] [ptr @_unnamed_cfstring_.2], section "__DATA,__objc_arraydata,regular,no_dead_strip", align 8
// CHECK: @_unnamed_nsdictionary_ = private constant %struct.__builtin_NSDictionary { ptr @"OBJC_CLASS_$_NSConstantDictionary", i64 1, i64 1, ptr @_unnamed_array_storage, ptr @_unnamed_array_storage.3 }, section "__DATA,__objc_dictobj,regular,no_dead_strip", align 8
// CHECK: @dict = global ptr @_unnamed_nsdictionary_, align 8
NSDictionary *dict = @{@"fast food" : @"burger"};
// CHECK: @"OBJC_CLASS_$_NSConstantIntegerNumber" = external global %struct._class_t
// CHECK: @.str.4 = private unnamed_addr constant [2 x i8] c"i\00", align 1
// CHECK: @_unnamed_nsconstantintegernumber_ = private constant %struct.__builtin_NSConstantIntegerNumber { ptr @"OBJC_CLASS_$_NSConstantIntegerNumber", ptr @.str.4, i64 42 }, section "__DATA,__objc_intobj,regular,no_dead_strip", align 8
// CHECK: @__kCFBooleanTrue = external global ptr
// CHECK: @"OBJC_CLASS_$_NSConstantArray" = external global %struct._class_t
// CHECK: @_unnamed_array_storage.5 = internal unnamed_addr constant [2 x ptr] [ptr @_unnamed_nsconstantintegernumber_, ptr @__kCFBooleanTrue], section "__DATA,__objc_arraydata,regular,no_dead_strip", align 8
// CHECK: @_unnamed_nsarray_ = private constant %struct.__builtin_NSArray { ptr @"OBJC_CLASS_$_NSConstantArray", i64 2, ptr @_unnamed_array_storage.5 }, section "__DATA,__objc_arrayobj,regular,no_dead_strip", align 8
// CHECK: @arr = global ptr @_unnamed_nsarray_, align 8
NSArray *arr = @[ @42, @YES ];
// CHECK: @"OBJC_CLASS_$_NSConstantDoubleNumber" = external global %struct._class_t
// CHECK: @_unnamed_nsconstantdoublenumber_ = private constant %struct.__builtin_NSConstantDoubleNumber { ptr @"OBJC_CLASS_$_NSConstantDoubleNumber", double 6.000000e+00 }, section "__DATA,__objc_doubleobj,regular,no_dead_strip", align 8
// CHECK: @num = global ptr @_unnamed_nsconstantdoublenumber_, align 8
NSNumber *num = @(2 + 4.0);
// CHECK: @_unnamed_nsconstantintegernumber_.6 = private constant %struct.__builtin_NSConstantIntegerNumber { ptr @"OBJC_CLASS_$_NSConstantIntegerNumber", ptr @.str.4, i64 17 }, section "__DATA,__objc_intobj,regular,no_dead_strip", align 8
// CHECK: @_unnamed_nsconstantintegernumber_.8 = private constant %struct.__builtin_NSConstantIntegerNumber { ptr @"OBJC_CLASS_$_NSConstantIntegerNumber", ptr @.str.7, i64 25 }, section "__DATA,__objc_intobj,regular,no_dead_strip", align 8
// CHECK: @_unnamed_nsconstantintegernumber_.10 = private constant %struct.__builtin_NSConstantIntegerNumber { ptr @"OBJC_CLASS_$_NSConstantIntegerNumber", ptr @.str.9, i64 42 }, section "__DATA,__objc_intobj,regular,no_dead_strip", align 8
// CHECK: @_unnamed_nsconstantintegernumber_.12 = private constant %struct.__builtin_NSConstantIntegerNumber { ptr @"OBJC_CLASS_$_NSConstantIntegerNumber", ptr @.str.11, i64 97 }, section "__DATA,__objc_intobj,regular,no_dead_strip", align 8
// Check globals are emitted for test_array
// CHECK: @_unnamed_array_storage.15 = internal unnamed_addr constant [2 x ptr] [ptr @_unnamed_cfstring_.14, ptr @_unnamed_nsconstantintegernumber_], section "__DATA,__objc_arraydata,regular,no_dead_strip", align 8
// CHECK: @_unnamed_nsarray_.16 = private constant %struct.__builtin_NSArray { ptr @"OBJC_CLASS_$_NSConstantArray", i64 2, ptr @_unnamed_array_storage.15 }, section "__DATA,__objc_arrayobj,regular,no_dead_strip", align 8
// Check globals are emitted for test_dictionary
// CHECK: @"OBJC_CLASS_$_NSConstantFloatNumber" = external global %struct._class_t
// CHECK: @_unnamed_nsconstantfloatnumber_ = private constant %struct.__builtin_NSConstantFloatNumber { ptr @"OBJC_CLASS_$_NSConstantFloatNumber", float 2.200000e+01 }, section "__DATA,__objc_floatobj,regular,no_dead_strip", align 8
// CHECK: @_unnamed_array_storage.27 = internal unnamed_addr constant [3 x ptr] [ptr @_unnamed_cfstring_.18, ptr @_unnamed_cfstring_.26, ptr @_unnamed_cfstring_.22], section "__DATA,__objc_arraydata,regular,no_dead_strip", align 8
// CHECK: @_unnamed_array_storage.28 = internal unnamed_addr constant [3 x ptr] [ptr @_unnamed_cfstring_.20, ptr @_unnamed_nsconstantfloatnumber_, ptr @_unnamed_cfstring_.24], section "__DATA,__objc_arraydata,regular,no_dead_strip", align 8
// CHECK: @_unnamed_nsdictionary_.29 = private constant %struct.__builtin_NSDictionary { ptr @"OBJC_CLASS_$_NSConstantDictionary", i64 1, i64 3, ptr @_unnamed_array_storage.27, ptr @_unnamed_array_storage.28 }, section "__DATA,__objc_dictobj,regular,no_dead_strip", align 8
// CHECK: @_unnamed_nsconstantintegernumber_.30 = private constant %struct.__builtin_NSConstantIntegerNumber { ptr @"OBJC_CLASS_$_NSConstantIntegerNumber", ptr @.str.9, i64 -1 }, section "__DATA,__objc_intobj,regular,no_dead_strip", align 8
// CHECK: @_unnamed_array_storage.31 = internal unnamed_addr constant [1 x ptr] [ptr @_unnamed_nsconstantintegernumber_.30], section "__DATA,__objc_arraydata,regular,no_dead_strip", align 8
// CHECK: @_unnamed_nsarray_.32 = private constant %struct.__builtin_NSArray { ptr @"OBJC_CLASS_$_NSConstantArray", i64 1, ptr @_unnamed_array_storage.31 }, section "__DATA,__objc_arrayobj,regular,no_dead_strip", align 8
// CHECK-LABEL: define void @test_numeric()
void test_numeric() {
// CHECK: call ptr @llvm.objc.retain(ptr @_unnamed_nsconstantintegernumber_.6)
id ilit = @17;
// CHECK: call ptr @llvm.objc.retain(ptr @_unnamed_nsconstantintegernumber_.8)
id ulit = @25u;
// CHECK: call ptr @llvm.objc.retain(ptr @_unnamed_nsconstantintegernumber_.10)
id ulllit = @42ull;
// CHECK: call ptr @llvm.objc.retain(ptr @_unnamed_nsconstantintegernumber_.12)
id charlit = @'a';
}
// CHECK-LABEL: define void @test_array
void test_array(id a, id b) {
// CHECK: call ptr @llvm.objc.retain(ptr @_unnamed_nsarray_.16)
id arr = @[ @"meaningOfLife", @42 ];
}
// CHECK-LABEL: define void @test_dictionary
void test_dictionary(id k1, id o1, id k2, id o2) {
// CHECK: call ptr @llvm.objc.retain(ptr @_unnamed_nsdictionary_.29)
id dict = @{@"fruit" : @"apple",
@"vegetable" : @"carrot",
@"number" : @22.0f};
}
// CHECK-LABEL: define void @test_int64array(
void test_int64array() {
// CHECK: call ptr @llvm.objc.retain(ptr @_unnamed_nsarray_.32)
id arr = @[@(0xFFFFFFFFFFFFFFFF)];
}
#endif