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 
1699451b44SJordan Rupprecht void caller_trivial_1 ();
1799451b44SJordan Rupprecht void caller_trivial_2 ();
1899451b44SJordan Rupprecht 
1999451b44SJordan Rupprecht void called_by_inline_trivial ();
2099451b44SJordan Rupprecht 
2199451b44SJordan Rupprecht static int inline_value;
2299451b44SJordan Rupprecht 
2399451b44SJordan Rupprecht int
function_to_call()2499451b44SJordan Rupprecht function_to_call ()
2599451b44SJordan Rupprecht {
2699451b44SJordan Rupprecht     return inline_value;
2799451b44SJordan Rupprecht }
2899451b44SJordan Rupprecht 
2999451b44SJordan Rupprecht int
caller_ref_1(int & value)3099451b44SJordan Rupprecht caller_ref_1 (int &value)
3199451b44SJordan Rupprecht {
3299451b44SJordan Rupprecht     int increment = caller_ref_2(value); // In caller_ref_1.
3399451b44SJordan Rupprecht     value += increment; // At increment in caller_ref_1.
3499451b44SJordan Rupprecht     return value;
3599451b44SJordan Rupprecht }
3699451b44SJordan Rupprecht 
3799451b44SJordan Rupprecht int
caller_ref_2(int & value)3899451b44SJordan Rupprecht caller_ref_2 (int &value)
3999451b44SJordan Rupprecht {
4099451b44SJordan Rupprecht     int increment = inline_ref_1 (value); // In caller_ref_2.
4199451b44SJordan Rupprecht     value += increment;  // At increment in caller_ref_2.
4299451b44SJordan Rupprecht     return value;
4399451b44SJordan Rupprecht }
4499451b44SJordan Rupprecht 
4599451b44SJordan Rupprecht int
called_by_inline_ref(int & value)4699451b44SJordan Rupprecht called_by_inline_ref (int &value)
4799451b44SJordan Rupprecht {
4899451b44SJordan Rupprecht     value += 1; // In called_by_inline_ref.
4999451b44SJordan Rupprecht     return value;
5099451b44SJordan Rupprecht }
5199451b44SJordan Rupprecht 
5299451b44SJordan Rupprecht int
inline_ref_1(int & value)5399451b44SJordan Rupprecht inline_ref_1 (int &value)
5499451b44SJordan Rupprecht {
5599451b44SJordan Rupprecht     int increment = inline_ref_2(value); // In inline_ref_1.
5699451b44SJordan Rupprecht     value += increment; // At increment in inline_ref_1.
5799451b44SJordan Rupprecht     return value;
5899451b44SJordan Rupprecht }
5999451b44SJordan Rupprecht 
6099451b44SJordan Rupprecht int
inline_ref_2(int & value)6199451b44SJordan Rupprecht inline_ref_2 (int &value)
6299451b44SJordan Rupprecht {
6399451b44SJordan Rupprecht     int increment = called_by_inline_ref (value);  // In inline_ref_2.
6499451b44SJordan Rupprecht     value += 1; // At increment in inline_ref_2.
6599451b44SJordan Rupprecht     return value;
6699451b44SJordan Rupprecht }
6799451b44SJordan Rupprecht 
6899451b44SJordan Rupprecht void
caller_trivial_1()6999451b44SJordan Rupprecht caller_trivial_1 ()
7099451b44SJordan Rupprecht {
7199451b44SJordan Rupprecht     caller_trivial_2(); // In caller_trivial_1.
7299451b44SJordan Rupprecht     inline_value += 1;
7399451b44SJordan Rupprecht }
7499451b44SJordan Rupprecht 
7599451b44SJordan Rupprecht void
caller_trivial_2()7699451b44SJordan Rupprecht caller_trivial_2 ()
7799451b44SJordan Rupprecht {
78*ecc6c426SFred Riss     asm volatile ("nop"); inline_trivial_1 (); // In caller_trivial_2.
7999451b44SJordan Rupprecht     inline_value += 1;  // At increment in caller_trivial_2.
8099451b44SJordan Rupprecht }
8199451b44SJordan Rupprecht 
8299451b44SJordan Rupprecht void
called_by_inline_trivial()8399451b44SJordan Rupprecht called_by_inline_trivial ()
8499451b44SJordan Rupprecht {
8599451b44SJordan Rupprecht     inline_value += 1; // In called_by_inline_trivial.
8699451b44SJordan Rupprecht }
8799451b44SJordan Rupprecht 
8899451b44SJordan Rupprecht void
inline_trivial_1()8999451b44SJordan Rupprecht inline_trivial_1 ()
9099451b44SJordan Rupprecht {
91*ecc6c426SFred Riss     asm volatile ("nop"); inline_trivial_2(); // In inline_trivial_1.
9299451b44SJordan Rupprecht     inline_value += 1;  // At increment in inline_trivial_1.
9399451b44SJordan Rupprecht }
9499451b44SJordan Rupprecht 
9599451b44SJordan Rupprecht void
inline_trivial_2()9699451b44SJordan Rupprecht inline_trivial_2 ()
9799451b44SJordan Rupprecht {
9899451b44SJordan Rupprecht     inline_value += 1; // In inline_trivial_2.
9999451b44SJordan Rupprecht     called_by_inline_trivial (); // At caller_by_inline_trivial in inline_trivial_2.
10099451b44SJordan Rupprecht }
10199451b44SJordan Rupprecht 
10299451b44SJordan Rupprecht template<typename T> T
max_value(const T & lhs,const T & rhs)10399451b44SJordan Rupprecht max_value(const T& lhs, const T& rhs)
10499451b44SJordan Rupprecht {
10599451b44SJordan Rupprecht     return std::max(lhs, rhs); // In max_value template
10699451b44SJordan Rupprecht }
10799451b44SJordan Rupprecht 
10899451b44SJordan Rupprecht template<> std::string
max_value(const std::string & lhs,const std::string & rhs)10999451b44SJordan Rupprecht max_value(const std::string& lhs, const std::string& rhs)
11099451b44SJordan Rupprecht {
11199451b44SJordan Rupprecht     return (lhs.size() > rhs.size()) ? lhs : rhs; // In max_value specialized
11299451b44SJordan Rupprecht }
11399451b44SJordan Rupprecht 
11499451b44SJordan Rupprecht int
main(int argc,char ** argv)11599451b44SJordan Rupprecht main (int argc, char **argv)
11699451b44SJordan Rupprecht {
11799451b44SJordan Rupprecht 
11899451b44SJordan Rupprecht     inline_value = 0;    // Stop here and step over to set up stepping over.
11999451b44SJordan Rupprecht 
12099451b44SJordan Rupprecht     inline_trivial_1 ();    // At inline_trivial_1 called from main.
12199451b44SJordan Rupprecht 
12299451b44SJordan Rupprecht     caller_trivial_1();     // At first call of caller_trivial_1 in main.
12399451b44SJordan Rupprecht 
12499451b44SJordan Rupprecht     caller_trivial_1();     // At second call of caller_trivial_1 in main.
12599451b44SJordan Rupprecht 
12699451b44SJordan Rupprecht     caller_ref_1 (argc); // At first call of caller_ref_1 in main.
12799451b44SJordan Rupprecht 
12899451b44SJordan Rupprecht     caller_ref_1 (argc); // At second call of caller_ref_1 in main.
12999451b44SJordan Rupprecht 
13099451b44SJordan Rupprecht     function_to_call (); // Make sure debug info for this function gets generated.
13199451b44SJordan Rupprecht 
13299451b44SJordan Rupprecht     max_value(123, 456);                                // Call max_value template
13399451b44SJordan Rupprecht     max_value(std::string("abc"), std::string("0022")); // Call max_value specialized
13499451b44SJordan Rupprecht 
13599451b44SJordan Rupprecht     return 0;            // About to return from main.
13699451b44SJordan Rupprecht }
137