Daily bump.
[gcc.git] / gcc / analyzer / program-point.h
1 /* Classes for representing locations within the program.
2 Copyright (C) 2019-2020 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
4
5 This file is part of GCC.
6
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.
11
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.
16
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/>. */
20
21 #ifndef GCC_ANALYZER_PROGRAM_POINT_H
22 #define GCC_ANALYZER_PROGRAM_POINT_H
23
24 namespace ana {
25
26 class exploded_graph;
27
28 /* An enum for distinguishing the various kinds of program_point. */
29
30 enum point_kind {
31 /* A "fake" node which has edges to all entrypoints. */
32 PK_ORIGIN,
33
34 PK_BEFORE_SUPERNODE,
35 PK_BEFORE_STMT,
36 PK_AFTER_SUPERNODE,
37
38 /* Special values used for hash_map: */
39 PK_EMPTY,
40 PK_DELETED,
41
42 NUM_POINT_KINDS
43 };
44
45 extern const char *point_kind_to_string (enum point_kind pk);
46
47 class format
48 {
49 public:
50 format (bool newlines) : m_newlines (newlines) {}
51
52 void spacer (pretty_printer *pp) const
53 {
54 if (m_newlines)
55 pp_newline (pp);
56 else
57 pp_space (pp);
58 }
59
60 bool m_newlines;
61 };
62
63 /* A class for representing a location within the program, without
64 interprocedural information.
65
66 This represents a fine-grained location within the supergraph (or
67 within one of its nodes). */
68
69 class function_point
70 {
71 public:
72 function_point (const supernode *supernode,
73 const superedge *from_edge,
74 unsigned stmt_idx,
75 enum point_kind kind);
76
77 void print (pretty_printer *pp, const format &f) const;
78 void print_source_line (pretty_printer *pp) const;
79 void dump () const;
80
81 hashval_t hash () const;
82 bool operator== (const function_point &other) const
83 {
84 return (m_supernode == other.m_supernode
85 && m_from_edge == other.m_from_edge
86 && m_stmt_idx == other.m_stmt_idx
87 && m_kind == other.m_kind);
88 }
89
90 /* Accessors. */
91
92 const supernode *get_supernode () const { return m_supernode; }
93 function *get_function () const;
94 const gimple *get_stmt () const;
95 location_t get_location () const;
96 enum point_kind get_kind () const { return m_kind; }
97 const superedge *get_from_edge () const
98 {
99 return m_from_edge;
100 }
101 unsigned get_stmt_idx () const
102 {
103 gcc_assert (m_kind == PK_BEFORE_STMT);
104 return m_stmt_idx;
105 }
106
107 /* Factory functions for making various kinds of program_point. */
108
109 static function_point from_function_entry (const supergraph &sg,
110 function *fun);
111
112 static function_point before_supernode (const supernode *supernode,
113 const superedge *from_edge);
114
115 static function_point before_stmt (const supernode *supernode,
116 unsigned stmt_idx)
117 {
118 return function_point (supernode, NULL, stmt_idx, PK_BEFORE_STMT);
119 }
120
121 static function_point after_supernode (const supernode *supernode)
122 {
123 return function_point (supernode, NULL, 0, PK_AFTER_SUPERNODE);
124 }
125
126 /* Support for hash_map. */
127
128 static function_point empty ()
129 {
130 return function_point (NULL, NULL, 0, PK_EMPTY);
131 }
132 static function_point deleted ()
133 {
134 return function_point (NULL, NULL, 0, PK_DELETED);
135 }
136
137 static int cmp_within_supernode_1 (const function_point &point_a,
138 const function_point &point_b);
139 static int cmp_within_supernode (const function_point &point_a,
140 const function_point &point_b);
141
142 /* For before_stmt, go to next stmt. */
143 void next_stmt ();
144
145 private:
146 const supernode *m_supernode;
147
148 /* For PK_BEFORE_SUPERNODE, and only for CFG edges. */
149 const superedge *m_from_edge;
150
151 /* Only for PK_BEFORE_STMT. */
152 unsigned m_stmt_idx;
153
154 enum point_kind m_kind;
155 };
156
157 /* A class for representing a location within the program, including
158 interprocedural information.
159
160 This represents a fine-grained location within the supergraph (or
161 within one of its nodes), along with a call string giving the
162 interprocedural context. */
163
164 class program_point
165 {
166 public:
167 program_point (const function_point &fn_point,
168 const call_string &call_string)
169 : m_function_point (fn_point),
170 m_call_string (call_string)
171 {
172 }
173
174 void print (pretty_printer *pp, const format &f) const;
175 void print_source_line (pretty_printer *pp) const;
176 void dump () const;
177
178 json::object *to_json () const;
179
180 hashval_t hash () const;
181 bool operator== (const program_point &other) const
182 {
183 return (m_function_point == other.m_function_point
184 && m_call_string == other.m_call_string);
185 }
186 bool operator!= (const program_point &other) const
187 {
188 return !(*this == other);
189 }
190
191 /* Accessors. */
192
193 const function_point &get_function_point () const { return m_function_point; }
194 const call_string &get_call_string () const { return m_call_string; }
195
196 const supernode *get_supernode () const
197 {
198 return m_function_point.get_supernode ();
199 }
200 function *get_function () const
201 {
202 return m_function_point.get_function ();
203 }
204 function *get_function_at_depth (unsigned depth) const;
205 tree get_fndecl () const
206 {
207 gcc_assert (get_kind () != PK_ORIGIN);
208 return get_function ()->decl;
209 }
210 const gimple *get_stmt () const
211 {
212 return m_function_point.get_stmt ();
213 }
214 location_t get_location () const
215 {
216 return m_function_point.get_location ();
217 }
218 enum point_kind get_kind () const
219 {
220 return m_function_point.get_kind ();
221 }
222 const superedge *get_from_edge () const
223 {
224 return m_function_point.get_from_edge ();
225 }
226 unsigned get_stmt_idx () const
227 {
228 return m_function_point.get_stmt_idx ();
229 }
230
231 /* Get the number of frames we expect at this program point.
232 This will be one more than the length of the call_string
233 (which stores the parent callsites), apart from the origin
234 node, which doesn't have any frames. */
235 int get_stack_depth () const
236 {
237 if (get_kind () == PK_ORIGIN)
238 return 0;
239 return m_call_string.length () + 1;
240 }
241
242 /* Factory functions for making various kinds of program_point. */
243 static program_point origin ()
244 {
245 return program_point (function_point (NULL, NULL,
246 0, PK_ORIGIN),
247 call_string ());
248 }
249
250 static program_point from_function_entry (const supergraph &sg,
251 function *fun)
252 {
253 return program_point (function_point::from_function_entry (sg, fun),
254 call_string ());
255 }
256
257 static program_point before_supernode (const supernode *supernode,
258 const superedge *from_edge,
259 const call_string &call_string)
260 {
261 return program_point (function_point::before_supernode (supernode,
262 from_edge),
263 call_string);
264 }
265
266 static program_point before_stmt (const supernode *supernode,
267 unsigned stmt_idx,
268 const call_string &call_string)
269 {
270 return program_point (function_point::before_stmt (supernode, stmt_idx),
271 call_string);
272 }
273
274 static program_point after_supernode (const supernode *supernode,
275 const call_string &call_string)
276 {
277 return program_point (function_point::after_supernode (supernode),
278 call_string);
279 }
280
281 /* Support for hash_map. */
282
283 static program_point empty ()
284 {
285 return program_point (function_point::empty (), call_string ());
286 }
287 static program_point deleted ()
288 {
289 return program_point (function_point::deleted (), call_string ());
290 }
291
292 bool on_edge (exploded_graph &eg, const superedge *succ);
293
294 void validate () const;
295
296 /* For before_stmt, go to next stmt. */
297 void next_stmt () { m_function_point.next_stmt (); }
298
299 program_point get_next () const;
300
301 private:
302 function_point m_function_point;
303 call_string m_call_string;
304 };
305
306 } // namespace ana
307
308 #endif /* GCC_ANALYZER_PROGRAM_POINT_H */