1 /* Classes for representing locations within the program.
2 Copyright (C) 2019-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)
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_PROGRAM_POINT_H
22 #define GCC_ANALYZER_PROGRAM_POINT_H
24 #include "pretty-print.h"
25 #include "analyzer/call-string.h"
31 /* An enum for distinguishing the various kinds of program_point. */
34 /* A "fake" node which has edges to all entrypoints. */
41 /* Special values used for hash_map: */
48 extern const char *point_kind_to_string (enum point_kind pk
);
53 format (bool newlines
) : m_newlines (newlines
) {}
55 void spacer (pretty_printer
*pp
) const
66 /* A class for representing a location within the program, without
67 interprocedural information.
69 This represents a fine-grained location within the supergraph (or
70 within one of its nodes). */
75 function_point (const supernode
*supernode
,
76 const superedge
*from_edge
,
78 enum point_kind kind
);
80 void print (pretty_printer
*pp
, const format
&f
) const;
81 void print_source_line (pretty_printer
*pp
) const;
84 hashval_t
hash () const;
85 bool operator== (const function_point
&other
) const
87 return (m_supernode
== other
.m_supernode
88 && m_from_edge
== other
.m_from_edge
89 && m_stmt_idx
== other
.m_stmt_idx
90 && m_kind
== other
.m_kind
);
95 const supernode
*get_supernode () const { return m_supernode
; }
96 function
*get_function () const;
97 const gimple
*get_stmt () const;
98 location_t
get_location () const;
99 enum point_kind
get_kind () const { return m_kind
; }
100 const superedge
*get_from_edge () const
104 unsigned get_stmt_idx () const
106 gcc_assert (m_kind
== PK_BEFORE_STMT
);
110 bool final_stmt_p () const;
112 /* Factory functions for making various kinds of program_point. */
114 static function_point
from_function_entry (const supergraph
&sg
,
115 const function
&fun
);
117 static function_point
before_supernode (const supernode
*supernode
,
118 const superedge
*from_edge
);
120 static function_point
before_stmt (const supernode
*supernode
,
123 return function_point (supernode
, NULL
, stmt_idx
, PK_BEFORE_STMT
);
126 static function_point
after_supernode (const supernode
*supernode
)
128 return function_point (supernode
, NULL
, 0, PK_AFTER_SUPERNODE
);
131 /* Support for hash_map. */
133 static function_point
empty ()
135 return function_point (NULL
, NULL
, 0, PK_EMPTY
);
137 static function_point
deleted ()
139 return function_point (NULL
, NULL
, 0, PK_DELETED
);
142 static int cmp_within_supernode_1 (const function_point
&point_a
,
143 const function_point
&point_b
);
144 static int cmp_within_supernode (const function_point
&point_a
,
145 const function_point
&point_b
);
146 static int cmp (const function_point
&point_a
,
147 const function_point
&point_b
);
148 static int cmp_ptr (const void *p1
, const void *p2
);
150 /* For before_stmt, go to next stmt. */
153 function_point
get_next () const;
156 const supernode
*m_supernode
;
158 /* For PK_BEFORE_SUPERNODE, and only for CFG edges. */
159 const superedge
*m_from_edge
;
161 /* Only for PK_BEFORE_STMT. */
164 enum point_kind m_kind
;
167 /* A class for representing a location within the program, including
168 interprocedural information.
170 This represents a fine-grained location within the supergraph (or
171 within one of its nodes), along with a call string giving the
172 interprocedural context. */
177 program_point (const function_point
&fn_point
,
178 const call_string
&call_string
)
179 : m_function_point (fn_point
),
180 m_call_string (&call_string
)
184 void print (pretty_printer
*pp
, const format
&f
) const;
187 std::unique_ptr
<json::object
> to_json () const;
189 hashval_t
hash () const;
190 bool operator== (const program_point
&other
) const
192 return (m_function_point
== other
.m_function_point
193 && m_call_string
== other
.m_call_string
);
195 bool operator!= (const program_point
&other
) const
197 return !(*this == other
);
202 const function_point
&get_function_point () const { return m_function_point
; }
203 const call_string
&get_call_string () const { return *m_call_string
; }
205 const supernode
*get_supernode () const
207 return m_function_point
.get_supernode ();
209 function
*get_function () const
211 return m_function_point
.get_function ();
213 function
*get_function_at_depth (unsigned depth
) const;
214 tree
get_fndecl () const
216 gcc_assert (get_kind () != PK_ORIGIN
);
217 return get_function ()->decl
;
219 const gimple
*get_stmt () const
221 return m_function_point
.get_stmt ();
223 location_t
get_location () const
225 return m_function_point
.get_location ();
227 enum point_kind
get_kind () const
229 return m_function_point
.get_kind ();
231 const superedge
*get_from_edge () const
233 return m_function_point
.get_from_edge ();
235 unsigned get_stmt_idx () const
237 return m_function_point
.get_stmt_idx ();
240 /* Get the number of frames we expect at this program point.
241 This will be one more than the length of the call_string
242 (which stores the parent callsites), apart from the origin
243 node, which doesn't have any frames. */
244 int get_stack_depth () const
246 if (get_kind () == PK_ORIGIN
)
248 return get_call_string ().length () + 1;
251 /* Factory functions for making various kinds of program_point. */
252 static program_point
origin (const region_model_manager
&mgr
);
253 static program_point
from_function_entry (const region_model_manager
&mgr
,
254 const supergraph
&sg
,
255 const function
&fun
);
257 static program_point
before_supernode (const supernode
*supernode
,
258 const superedge
*from_edge
,
259 const call_string
&call_string
)
261 return program_point (function_point::before_supernode (supernode
,
266 static program_point
before_stmt (const supernode
*supernode
,
268 const call_string
&call_string
)
270 return program_point (function_point::before_stmt (supernode
, stmt_idx
),
274 static program_point
after_supernode (const supernode
*supernode
,
275 const call_string
&call_string
)
277 return program_point (function_point::after_supernode (supernode
),
281 /* Support for hash_map. */
283 static program_point
empty ()
285 return program_point (function_point::empty ());
287 static program_point
deleted ()
289 return program_point (function_point::deleted ());
292 bool on_edge (exploded_graph
&eg
, const superedge
*succ
);
293 void push_to_call_stack (const supernode
*caller
, const supernode
*callee
);
294 void pop_from_call_stack ();
295 void validate () const;
297 /* For before_stmt, go to next stmt. */
298 void next_stmt () { m_function_point
.next_stmt (); }
300 program_point
get_next () const;
302 static bool effectively_intraprocedural_p (const program_point
&point_a
,
303 const program_point
&point_b
);
306 program_point (const function_point
&fn_point
)
307 : m_function_point (fn_point
),
312 function_point m_function_point
;
313 const call_string
*m_call_string
;
318 #endif /* GCC_ANALYZER_PROGRAM_POINT_H */