1 // RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o %t 2 // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-GLOBALS 3 // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-1 4 // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-2 5 // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-3 6 7 typedef __INTPTR_TYPE__ intptr_t; 8 9 int foo(); 10 int global; 11 12 // Single statement 13 void test1() { 14 int i = 0; 15 #pragma clang __debug captured 16 { 17 static float inner = 3.0; 18 (void)inner; 19 i++; 20 } 21 // CHECK-1: %struct.anon = type { i32* } 22 // CHECK-1: {{.+}} global float 3.0 23 // 24 // CHECK-1: @test1( 25 // CHECK-1: alloca %struct.anon 26 // CHECK-1: getelementptr inbounds %struct.anon, %struct.anon* 27 // CHECK-1: store i32* %i 28 // CHECK-1: call void @[[HelperName:__captured_stmt[\.0-9]+]] 29 } 30 31 // CHECK-1: define internal {{.*}}void @[[HelperName]](%struct.anon 32 // CHECK-1: getelementptr inbounds %struct.anon{{.*}}, i32 0, i32 0 33 // CHECK-1: load i32*, i32** 34 // CHECK-1: load i32, i32* 35 // CHECK-1: add nsw i32 36 // CHECK-1: store i32 37 38 // Compound statement with local variable 39 void test2(int x) { 40 #pragma clang __debug captured 41 { 42 int i; 43 for (i = 0; i < x; i++) 44 foo(); 45 } 46 // CHECK-2: @test2( 47 // CHECK-2-NOT: %i 48 // CHECK-2: call void @[[HelperName:__captured_stmt[\.0-9]+]] 49 } 50 51 // CHECK-2: define internal {{.*}}void @[[HelperName]] 52 // CHECK-2-NOT: } 53 // CHECK-2: %i = alloca i32 54 55 // Capture array 56 void test3(int size) { 57 int arr[] = {1, 2, 3, 4, 5}; 58 int vla_arr[size]; 59 #pragma clang __debug captured 60 { 61 arr[2] = vla_arr[size - 1]; 62 } 63 // CHECK-3: @test3( 64 // CHECK-3: alloca [5 x i32] 65 // CHECK-3: call void @__captured_stmt 66 } 67 68 // Capture VLA array 69 void test4(intptr_t size, intptr_t vla_arr[size]) { 70 #pragma clang __debug captured 71 { 72 vla_arr[0] = 1; 73 } 74 // CHECK-3: test4([[INTPTR_T:i.+]] {{.*}}[[SIZE_ARG:%.+]], [[INTPTR_T]]* 75 // CHECK-3: store [[INTPTR_T]] {{.*}}[[SIZE_ARG]], [[INTPTR_T]]* [[SIZE_ADDR:%.+]], 76 // CHECK-3: [[SIZE:%.+]] = load [[INTPTR_T]], [[INTPTR_T]]* [[SIZE_ADDR]], 77 // CHECK-3: [[REF:%.+]] = getelementptr inbounds 78 // CHECK-3: store [[INTPTR_T]] [[SIZE]], [[INTPTR_T]]* [[REF]] 79 // CHECK-3: call void @__captured_stmt 80 } 81 82 void dont_capture_global() { 83 static int s; 84 extern int e; 85 #pragma clang __debug captured 86 { 87 global++; 88 s++; 89 e++; 90 } 91 92 // CHECK-GLOBALS: %[[Capture:struct\.anon[\.0-9]*]] = type {} 93 // CHECK-GLOBALS: call void @__captured_stmt[[HelperName:[\.0-9]+]](%[[Capture]] 94 } 95 96 // CHECK-GLOBALS: define internal {{.*}}void @__captured_stmt[[HelperName]] 97 // CHECK-GLOBALS-NOT: ret 98 // CHECK-GLOBALS: load i32, i32* @global 99 // CHECK-GLOBALS: load i32, i32* @ 100 // CHECK-GLOBALS: load i32, i32* @e 101