Clang Project

clang_source_code/test/CodeGenCXX/linetable-cleanup.cpp
1// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
2// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin10 -std=c++98 %s -o - | FileCheck %s
3// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin10 -std=c++11 %s -o - | FileCheck %s
4
5// Check the line numbers for cleanup code with EH in combination with
6// simple return expressions.
7
8// CHECK: define {{.*}}foo
9// CHECK: call void @_ZN1CD1Ev(%class.C* {{.*}}){{( #[0-9])?}}, !dbg ![[RET:[0-9]+]]
10// CHECK: ret i32 0, !dbg ![[RET]]
11
12// CHECK: define {{.*}}bar
13// CHECK: ret void, !dbg ![[RETBAR:[0-9]+]]
14
15// CHECK: define {{.*}}baz
16// CHECK: ret void, !dbg ![[RETBAZ:[0-9]+]]
17
18class C {
19public:
20  ~C() {}
21  int i;
22};
23
24int foo()
25{
26  C c;
27  c.i = 42;
28  return 0;
29  // This breakpoint should be at/before the cleanup code.
30  // CHECK: ![[RET]] = !DILocation(line: [[@LINE+1]], scope: !{{.*}})
31}
32
33void bar()
34{
35  if (!foo())
36    // CHECK: {{.*}} = !DILocation(line: [[@LINE+1]], scope: !{{.*}})
37    return;
38
39  if (foo()) {
40    C c;
41    c.i = foo();
42  }
43  // Clang creates only a single ret instruction. Make sure it is at a useful line.
44  // CHECK: ![[RETBAR]] = !DILocation(line: [[@LINE+1]], scope: !{{.*}})
45}
46
47void baz()
48{
49  if (!foo())
50    // CHECK: ![[SCOPE1:.*]] = distinct !DILexicalBlock({{.*}}, line: [[@LINE-1]])
51    // CHECK: {{.*}} = !DILocation(line: [[@LINE+1]], scope: ![[SCOPE1]])
52    return;
53
54  if (foo()) {
55    // no cleanup
56    // CHECK: {{.*}} = !DILocation(line: [[@LINE+2]], scope: ![[SCOPE2:.*]])
57    // CHECK: ![[SCOPE2]] = distinct !DILexicalBlock({{.*}}, line: [[@LINE-3]])
58    return;
59  }
60  // CHECK: ![[RETBAZ]] = !DILocation(line: [[@LINE+1]], scope: !{{.*}})
61}
62