1*f313ed5bSErich Keane // RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCallGraph %s -fblocks 2>&1 | FileCheck %s 2*f313ed5bSErich Keane 3*f313ed5bSErich Keane int get5() { 4*f313ed5bSErich Keane return 5; 5*f313ed5bSErich Keane } 6*f313ed5bSErich Keane 7*f313ed5bSErich Keane int add(int val1, int val2) { 8*f313ed5bSErich Keane return val1 + val2; 9*f313ed5bSErich Keane } 10*f313ed5bSErich Keane 11*f313ed5bSErich Keane int test_add() { 12*f313ed5bSErich Keane return add(10, get5()); 13*f313ed5bSErich Keane } 14*f313ed5bSErich Keane 15*f313ed5bSErich Keane static void mmm(int y) { 16*f313ed5bSErich Keane if (y != 0) 17*f313ed5bSErich Keane y++; 18*f313ed5bSErich Keane y = y/y; 19*f313ed5bSErich Keane } 20*f313ed5bSErich Keane 21*f313ed5bSErich Keane static int foo(int x, int y) { 22*f313ed5bSErich Keane mmm(y); 23*f313ed5bSErich Keane if (x != 0) 24*f313ed5bSErich Keane x++; 25*f313ed5bSErich Keane return 5/x; 26*f313ed5bSErich Keane } 27*f313ed5bSErich Keane 28*f313ed5bSErich Keane void aaa() { 29*f313ed5bSErich Keane foo(1,2); 30*f313ed5bSErich Keane } 31*f313ed5bSErich Keane 32*f313ed5bSErich Keane void bbb(int y) { 33*f313ed5bSErich Keane int x = (y > 2); 34*f313ed5bSErich Keane ^ { 35*f313ed5bSErich Keane foo(x, y); 36*f313ed5bSErich Keane }(); 37*f313ed5bSErich Keane } 38*f313ed5bSErich Keane void ccc(); 39*f313ed5bSErich Keane void ddd() { ccc(); } 40*f313ed5bSErich Keane void ccc() {} 41*f313ed5bSErich Keane 42*f313ed5bSErich Keane void eee(); 43*f313ed5bSErich Keane void eee() {} 44*f313ed5bSErich Keane void fff() { eee(); } 45*f313ed5bSErich Keane 46*f313ed5bSErich Keane // This test case tests that forward declaration for the top-level function 47*f313ed5bSErich Keane // does not affect call graph construction. 48*f313ed5bSErich Keane void do_nothing() {} 49*f313ed5bSErich Keane void test_single_call(); 50*f313ed5bSErich Keane void test_single_call() { 51*f313ed5bSErich Keane do_nothing(); 52*f313ed5bSErich Keane } 53*f313ed5bSErich Keane 54*f313ed5bSErich Keane template<typename T> 55*f313ed5bSErich Keane void templ(T t) { 56*f313ed5bSErich Keane ccc(); 57*f313ed5bSErich Keane } 58*f313ed5bSErich Keane 59*f313ed5bSErich Keane template<> 60*f313ed5bSErich Keane void templ<double>(double t) { 61*f313ed5bSErich Keane eee(); 62*f313ed5bSErich Keane } 63*f313ed5bSErich Keane 64*f313ed5bSErich Keane 65*f313ed5bSErich Keane void templUser() { 66*f313ed5bSErich Keane templ(5); 67*f313ed5bSErich Keane templ(5.5); 68*f313ed5bSErich Keane } 69*f313ed5bSErich Keane 70*f313ed5bSErich Keane // CHECK:--- Call graph Dump --- 71*f313ed5bSErich Keane // CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa < > bbb ddd ccc eee fff do_nothing test_single_call templ templ templUser $}} 72*f313ed5bSErich Keane // CHECK-NEXT: {{Function: templUser calls: templ templ $}} 73*f313ed5bSErich Keane // CHECK-NEXT: {{Function: templ calls: eee $}} 74*f313ed5bSErich Keane // CHECK-NEXT: {{Function: templ calls: ccc $}} 75*f313ed5bSErich Keane // CHECK-NEXT: {{Function: test_single_call calls: do_nothing $}} 76*f313ed5bSErich Keane // CHECK-NEXT: {{Function: do_nothing calls: $}} 77*f313ed5bSErich Keane // CHECK-NEXT: {{Function: fff calls: eee $}} 78*f313ed5bSErich Keane // CHECK-NEXT: {{Function: eee calls: $}} 79*f313ed5bSErich Keane // CHECK-NEXT: {{Function: ddd calls: ccc $}} 80*f313ed5bSErich Keane // CHECK-NEXT: {{Function: ccc calls: $}} 81*f313ed5bSErich Keane // CHECK-NEXT: {{Function: bbb calls: < > $}} 82*f313ed5bSErich Keane // CHECK-NEXT: {{Function: < > calls: foo $}} 83*f313ed5bSErich Keane // CHECK-NEXT: {{Function: aaa calls: foo $}} 84*f313ed5bSErich Keane // CHECK-NEXT: {{Function: foo calls: mmm $}} 85*f313ed5bSErich Keane // CHECK-NEXT: {{Function: mmm calls: $}} 86*f313ed5bSErich Keane // CHECK-NEXT: {{Function: test_add calls: add get5 $}} 87*f313ed5bSErich Keane // CHECK-NEXT: {{Function: add calls: $}} 88*f313ed5bSErich Keane // CHECK-NEXT: {{Function: get5 calls: $}} 89