1 #include <algorithm> 2 #include <cstdio> 3 #include <string> 4 5 inline int inline_ref_1 (int &value) __attribute__((always_inline)); 6 inline int inline_ref_2 (int &value) __attribute__((always_inline)); 7 8 int caller_ref_1 (int &value); 9 int caller_ref_2 (int &value); 10 11 int called_by_inline_ref (int &value); 12 13 inline void inline_trivial_1 () __attribute__((always_inline)); 14 inline void inline_trivial_2 () __attribute__((always_inline)); 15 16 // These three should share the same initial pc so we can test 17 // virtual inline stepping. 18 inline void caller_trivial_inline_1() __attribute__((always_inline)); 19 inline void caller_trivial_inline_2() __attribute__((always_inline)); 20 inline void caller_trivial_inline_3() __attribute__((always_inline)); 21 22 void caller_trivial_1 (); 23 void caller_trivial_2 (); 24 25 void called_by_inline_trivial (); 26 27 static int inline_value; 28 29 int 30 function_to_call () 31 { 32 return inline_value; 33 } 34 35 int 36 caller_ref_1 (int &value) 37 { 38 int increment = caller_ref_2(value); // In caller_ref_1. 39 value += increment; // At increment in caller_ref_1. 40 return value; 41 } 42 43 int 44 caller_ref_2 (int &value) 45 { 46 int increment = inline_ref_1 (value); // In caller_ref_2. 47 value += increment; // At increment in caller_ref_2. 48 return value; 49 } 50 51 int 52 called_by_inline_ref (int &value) 53 { 54 value += 1; // In called_by_inline_ref. 55 return value; 56 } 57 58 int 59 inline_ref_1 (int &value) 60 { 61 int increment = inline_ref_2(value); // In inline_ref_1. 62 value += increment; // At increment in inline_ref_1. 63 return value; 64 } 65 66 int 67 inline_ref_2 (int &value) 68 { 69 int increment = called_by_inline_ref (value); // In inline_ref_2. 70 value += 1; // At increment in inline_ref_2. 71 return value; 72 } 73 74 void 75 caller_trivial_1 () 76 { 77 caller_trivial_2(); // In caller_trivial_1. 78 inline_value += 1; 79 } 80 81 void 82 caller_trivial_2 () 83 { 84 asm volatile ("nop"); inline_trivial_1 (); // In caller_trivial_2. 85 inline_value += 1; // At increment in caller_trivial_2. 86 } 87 88 // When you call caller_trivial_inline_1, the inlined call-site 89 // should share a PC with all three of the following inlined 90 // functions, so we can exercise "virtual inline stepping". 91 void caller_trivial_inline_1() { 92 caller_trivial_inline_2(); // In caller_trivial_inline_1. 93 inline_value += 1; 94 } 95 96 void caller_trivial_inline_2() { 97 caller_trivial_inline_3(); // In caller_trivial_inline_2. 98 inline_value += 1; // After caller_trivial_inline_3 99 } 100 101 void caller_trivial_inline_3() { 102 inline_value += 1; // In caller_trivial_inline_3. 103 } 104 105 void 106 called_by_inline_trivial () 107 { 108 inline_value += 1; // In called_by_inline_trivial. 109 } 110 111 void 112 inline_trivial_1 () 113 { 114 asm volatile ("nop"); inline_trivial_2(); // In inline_trivial_1. 115 inline_value += 1; // At increment in inline_trivial_1. 116 } 117 118 void 119 inline_trivial_2 () 120 { 121 inline_value += 1; // In inline_trivial_2. 122 called_by_inline_trivial (); // At caller_by_inline_trivial in inline_trivial_2. 123 } 124 125 template<typename T> T 126 max_value(const T& lhs, const T& rhs) 127 { 128 return std::max(lhs, rhs); // In max_value template 129 } 130 131 template<> std::string 132 max_value(const std::string& lhs, const std::string& rhs) 133 { 134 return (lhs.size() > rhs.size()) ? lhs : rhs; // In max_value specialized 135 } 136 137 int 138 main (int argc, char **argv) 139 { 140 141 inline_value = 0; // Stop here and step over to set up stepping over. 142 143 inline_trivial_1 (); // At inline_trivial_1 called from main. 144 145 caller_trivial_1(); // At first call of caller_trivial_1 in main. 146 147 caller_trivial_1(); // At second call of caller_trivial_1 in main. 148 149 caller_ref_1 (argc); // At first call of caller_ref_1 in main. 150 151 caller_ref_1 (argc); // At second call of caller_ref_1 in main. 152 153 function_to_call (); // Make sure debug info for this function gets generated. 154 155 max_value(123, 456); // Call max_value template 156 max_value(std::string("abc"), std::string("0022")); // Call max_value specialized 157 158 caller_trivial_inline_1(); // At caller_trivial_inline_1. 159 160 return 0; // About to return from main. 161 } 162