199451b44SJordan Rupprecht #include <algorithm> 299451b44SJordan Rupprecht #include <cstdio> 399451b44SJordan Rupprecht #include <string> 499451b44SJordan Rupprecht 599451b44SJordan Rupprecht inline int inline_ref_1 (int &value) __attribute__((always_inline)); 699451b44SJordan Rupprecht inline int inline_ref_2 (int &value) __attribute__((always_inline)); 799451b44SJordan Rupprecht 899451b44SJordan Rupprecht int caller_ref_1 (int &value); 999451b44SJordan Rupprecht int caller_ref_2 (int &value); 1099451b44SJordan Rupprecht 1199451b44SJordan Rupprecht int called_by_inline_ref (int &value); 1299451b44SJordan Rupprecht 1399451b44SJordan Rupprecht inline void inline_trivial_1 () __attribute__((always_inline)); 1499451b44SJordan Rupprecht inline void inline_trivial_2 () __attribute__((always_inline)); 1599451b44SJordan Rupprecht 167dbbd2b2Sjimingham // These three should share the same initial pc so we can test 177dbbd2b2Sjimingham // virtual inline stepping. 187dbbd2b2Sjimingham inline void caller_trivial_inline_1() __attribute__((always_inline)); 197dbbd2b2Sjimingham inline void caller_trivial_inline_2() __attribute__((always_inline)); 207dbbd2b2Sjimingham inline void caller_trivial_inline_3() __attribute__((always_inline)); 217dbbd2b2Sjimingham 2299451b44SJordan Rupprecht void caller_trivial_1 (); 2399451b44SJordan Rupprecht void caller_trivial_2 (); 2499451b44SJordan Rupprecht 2599451b44SJordan Rupprecht void called_by_inline_trivial (); 2699451b44SJordan Rupprecht 2799451b44SJordan Rupprecht static int inline_value; 2899451b44SJordan Rupprecht 2999451b44SJordan Rupprecht int 3099451b44SJordan Rupprecht function_to_call () 3199451b44SJordan Rupprecht { 3299451b44SJordan Rupprecht return inline_value; 3399451b44SJordan Rupprecht } 3499451b44SJordan Rupprecht 3599451b44SJordan Rupprecht int 3699451b44SJordan Rupprecht caller_ref_1 (int &value) 3799451b44SJordan Rupprecht { 3899451b44SJordan Rupprecht int increment = caller_ref_2(value); // In caller_ref_1. 3999451b44SJordan Rupprecht value += increment; // At increment in caller_ref_1. 4099451b44SJordan Rupprecht return value; 4199451b44SJordan Rupprecht } 4299451b44SJordan Rupprecht 4399451b44SJordan Rupprecht int 4499451b44SJordan Rupprecht caller_ref_2 (int &value) 4599451b44SJordan Rupprecht { 4699451b44SJordan Rupprecht int increment = inline_ref_1 (value); // In caller_ref_2. 4799451b44SJordan Rupprecht value += increment; // At increment in caller_ref_2. 4899451b44SJordan Rupprecht return value; 4999451b44SJordan Rupprecht } 5099451b44SJordan Rupprecht 5199451b44SJordan Rupprecht int 5299451b44SJordan Rupprecht called_by_inline_ref (int &value) 5399451b44SJordan Rupprecht { 5499451b44SJordan Rupprecht value += 1; // In called_by_inline_ref. 5599451b44SJordan Rupprecht return value; 5699451b44SJordan Rupprecht } 5799451b44SJordan Rupprecht 5899451b44SJordan Rupprecht int 5999451b44SJordan Rupprecht inline_ref_1 (int &value) 6099451b44SJordan Rupprecht { 6199451b44SJordan Rupprecht int increment = inline_ref_2(value); // In inline_ref_1. 6299451b44SJordan Rupprecht value += increment; // At increment in inline_ref_1. 6399451b44SJordan Rupprecht return value; 6499451b44SJordan Rupprecht } 6599451b44SJordan Rupprecht 6699451b44SJordan Rupprecht int 6799451b44SJordan Rupprecht inline_ref_2 (int &value) 6899451b44SJordan Rupprecht { 6999451b44SJordan Rupprecht int increment = called_by_inline_ref (value); // In inline_ref_2. 7099451b44SJordan Rupprecht value += 1; // At increment in inline_ref_2. 7199451b44SJordan Rupprecht return value; 7299451b44SJordan Rupprecht } 7399451b44SJordan Rupprecht 7499451b44SJordan Rupprecht void 7599451b44SJordan Rupprecht caller_trivial_1 () 7699451b44SJordan Rupprecht { 7799451b44SJordan Rupprecht caller_trivial_2(); // In caller_trivial_1. 7899451b44SJordan Rupprecht inline_value += 1; 7999451b44SJordan Rupprecht } 8099451b44SJordan Rupprecht 8199451b44SJordan Rupprecht void 8299451b44SJordan Rupprecht caller_trivial_2 () 8399451b44SJordan Rupprecht { 84ecc6c426SFred Riss asm volatile ("nop"); inline_trivial_1 (); // In caller_trivial_2. 8599451b44SJordan Rupprecht inline_value += 1; // At increment in caller_trivial_2. 8699451b44SJordan Rupprecht } 8799451b44SJordan Rupprecht 887dbbd2b2Sjimingham // When you call caller_trivial_inline_1, the inlined call-site 897dbbd2b2Sjimingham // should share a PC with all three of the following inlined 907dbbd2b2Sjimingham // functions, so we can exercise "virtual inline stepping". 917dbbd2b2Sjimingham void caller_trivial_inline_1() { 927dbbd2b2Sjimingham caller_trivial_inline_2(); // In caller_trivial_inline_1. 937dbbd2b2Sjimingham inline_value += 1; 947dbbd2b2Sjimingham } 957dbbd2b2Sjimingham 967dbbd2b2Sjimingham void caller_trivial_inline_2() { 977dbbd2b2Sjimingham caller_trivial_inline_3(); // In caller_trivial_inline_2. 98*3243e3d8Sjimingham inline_value += 1; // After caller_trivial_inline_3 997dbbd2b2Sjimingham } 1007dbbd2b2Sjimingham 1017dbbd2b2Sjimingham void caller_trivial_inline_3() { 1027dbbd2b2Sjimingham inline_value += 1; // In caller_trivial_inline_3. 1037dbbd2b2Sjimingham } 1047dbbd2b2Sjimingham 10599451b44SJordan Rupprecht void 10699451b44SJordan Rupprecht called_by_inline_trivial () 10799451b44SJordan Rupprecht { 10899451b44SJordan Rupprecht inline_value += 1; // In called_by_inline_trivial. 10999451b44SJordan Rupprecht } 11099451b44SJordan Rupprecht 11199451b44SJordan Rupprecht void 11299451b44SJordan Rupprecht inline_trivial_1 () 11399451b44SJordan Rupprecht { 114ecc6c426SFred Riss asm volatile ("nop"); inline_trivial_2(); // In inline_trivial_1. 11599451b44SJordan Rupprecht inline_value += 1; // At increment in inline_trivial_1. 11699451b44SJordan Rupprecht } 11799451b44SJordan Rupprecht 11899451b44SJordan Rupprecht void 11999451b44SJordan Rupprecht inline_trivial_2 () 12099451b44SJordan Rupprecht { 12199451b44SJordan Rupprecht inline_value += 1; // In inline_trivial_2. 12299451b44SJordan Rupprecht called_by_inline_trivial (); // At caller_by_inline_trivial in inline_trivial_2. 12399451b44SJordan Rupprecht } 12499451b44SJordan Rupprecht 12599451b44SJordan Rupprecht template<typename T> T 12699451b44SJordan Rupprecht max_value(const T& lhs, const T& rhs) 12799451b44SJordan Rupprecht { 12899451b44SJordan Rupprecht return std::max(lhs, rhs); // In max_value template 12999451b44SJordan Rupprecht } 13099451b44SJordan Rupprecht 13199451b44SJordan Rupprecht template<> std::string 13299451b44SJordan Rupprecht max_value(const std::string& lhs, const std::string& rhs) 13399451b44SJordan Rupprecht { 13499451b44SJordan Rupprecht return (lhs.size() > rhs.size()) ? lhs : rhs; // In max_value specialized 13599451b44SJordan Rupprecht } 13699451b44SJordan Rupprecht 13799451b44SJordan Rupprecht int 13899451b44SJordan Rupprecht main (int argc, char **argv) 13999451b44SJordan Rupprecht { 14099451b44SJordan Rupprecht 14199451b44SJordan Rupprecht inline_value = 0; // Stop here and step over to set up stepping over. 14299451b44SJordan Rupprecht 14399451b44SJordan Rupprecht inline_trivial_1 (); // At inline_trivial_1 called from main. 14499451b44SJordan Rupprecht 14599451b44SJordan Rupprecht caller_trivial_1(); // At first call of caller_trivial_1 in main. 14699451b44SJordan Rupprecht 14799451b44SJordan Rupprecht caller_trivial_1(); // At second call of caller_trivial_1 in main. 14899451b44SJordan Rupprecht 14999451b44SJordan Rupprecht caller_ref_1 (argc); // At first call of caller_ref_1 in main. 15099451b44SJordan Rupprecht 15199451b44SJordan Rupprecht caller_ref_1 (argc); // At second call of caller_ref_1 in main. 15299451b44SJordan Rupprecht 15399451b44SJordan Rupprecht function_to_call (); // Make sure debug info for this function gets generated. 15499451b44SJordan Rupprecht 15599451b44SJordan Rupprecht max_value(123, 456); // Call max_value template 15699451b44SJordan Rupprecht max_value(std::string("abc"), std::string("0022")); // Call max_value specialized 15799451b44SJordan Rupprecht 1587dbbd2b2Sjimingham caller_trivial_inline_1(); // At caller_trivial_inline_1. 1597dbbd2b2Sjimingham 16099451b44SJordan Rupprecht return 0; // About to return from main. 16199451b44SJordan Rupprecht } 162