d: Add test for PR d/108167 to the testsuite [PR108167]
[official-gcc.git] / gcc / analyzer / inlining-iterator.h
blob7d4798ce6ea532ddba58aea56d73892cf9f5831a
1 /* Iterator for walking a chain of inlining locations.
2 Copyright (C) 2022-2023 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 #endif /* GCC_ANALYZER_INLINING_ITERATOR_H */