install.texi (gcn): Suggest newer commit for Newlib
[official-gcc.git] / gcc / analyzer / inlining-iterator.h
blobe65caa472cee2ac4c4d36f319ea8298cc8d9cd87
1 /* Iterator for walking a chain of inlining locations.
2 Copyright (C) 2022-2024 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #ifndef GCC_ANALYZER_INLINING_ITERATOR_H
22 #define GCC_ANALYZER_INLINING_ITERATOR_H
24 /* Iterator for walking a chain of inlining locations.
26 The fndecls and locations will be traversed from innermost to outermost.
27 For example, given:
29 inline void inner (void)
31 ...LOCATION HERE...
33 void outer (void)
35 inner (); <-- CALLSITE
38 then the fndecl will be "inner" on the initial iteration, and "outer" on
39 the second (final) iteration.
41 Compare with lhd_print_error_function, cp_print_error_function,
42 and optrecord_json_writer::inlining_chain_to_json. */
44 class inlining_iterator
46 public:
47 inlining_iterator (location_t loc)
48 : m_abstract_origin (LOCATION_BLOCK (loc)),
49 m_callsite (UNKNOWN_LOCATION), m_fndecl (NULL),
50 m_next_abstract_origin (NULL)
52 prepare_iteration ();
55 bool done_p () const { return m_abstract_origin == NULL; }
57 void next ()
59 m_abstract_origin = m_next_abstract_origin;
60 prepare_iteration ();
63 tree get_fndecl () const { return m_fndecl; }
64 location_t get_callsite () const { return m_callsite; }
65 tree get_block () const { return m_abstract_origin; }
67 private:
68 void prepare_iteration ()
70 if (done_p ())
71 return;
72 tree block = m_abstract_origin;
73 m_callsite = BLOCK_SOURCE_LOCATION (block);
74 m_fndecl = NULL;
75 block = BLOCK_SUPERCONTEXT (block);
76 while (block && TREE_CODE (block) == BLOCK
77 && BLOCK_ABSTRACT_ORIGIN (block))
79 tree ao = BLOCK_ABSTRACT_ORIGIN (block);
80 if (TREE_CODE (ao) == FUNCTION_DECL)
82 m_fndecl = ao;
83 break;
85 else if (TREE_CODE (ao) != BLOCK)
86 break;
88 block = BLOCK_SUPERCONTEXT (block);
90 if (m_fndecl)
91 m_next_abstract_origin = block;
92 else
94 while (block && TREE_CODE (block) == BLOCK)
95 block = BLOCK_SUPERCONTEXT (block);
97 if (block && TREE_CODE (block) == FUNCTION_DECL)
98 m_fndecl = block;
99 m_next_abstract_origin = NULL;
103 tree m_abstract_origin;
104 location_t m_callsite;
105 tree m_fndecl;
106 tree m_next_abstract_origin;
109 /* A class for fixing up fndecls and stack depths in checker_event, based
110 on inlining records.
112 The early inliner runs before the analyzer, which can lead to confusing
113 output.
115 Tne base fndecl and depth within a checker_event are from call strings
116 in program_points, which reflect the call strings after inlining.
117 This class lets us offset the depth and fix up the reported fndecl and
118 stack depth to better reflect the user's original code. */
120 class inlining_info
122 public:
123 inlining_info (location_t loc)
125 inlining_iterator iter (loc);
126 m_inner_fndecl = iter.get_fndecl ();
127 int num_frames = 0;
128 while (!iter.done_p ())
130 m_outer_fndecl = iter.get_fndecl ();
131 num_frames++;
132 iter.next ();
134 if (num_frames > 1)
135 m_extra_frames = num_frames - 1;
136 else
137 m_extra_frames = 0;
140 tree get_inner_fndecl () const { return m_inner_fndecl; }
141 int get_extra_frames () const { return m_extra_frames; }
143 private:
144 tree m_outer_fndecl;
145 tree m_inner_fndecl;
146 int m_extra_frames;
149 #endif /* GCC_ANALYZER_INLINING_ITERATOR_H */