Branch data Line data Source code
1 : : // parse tree functions
2 : : // Copyright (C) 2005-2011 Red Hat Inc.
3 : : //
4 : : // This file is part of systemtap, and is free software. You can
5 : : // redistribute it and/or modify it under the terms of the GNU General
6 : : // Public License (GPL); either version 2, or (at your option) any
7 : : // later version.
8 : :
9 : : #include "config.h"
10 : : #include "staptree.h"
11 : : #include "parse.h"
12 : : #include "util.h"
13 : : #include "session.h"
14 : :
15 : : #include <iostream>
16 : : #include <typeinfo>
17 : : #include <sstream>
18 : : #include <cassert>
19 : : #include <cstring>
20 : : #include <vector>
21 : : #include <algorithm>
22 : : #include <cstring>
23 : :
24 : : using namespace std;
25 : :
26 : :
27 : :
28 : 21327 : visitable::~visitable ()
29 : : {
30 [ - + ]: 21327 : }
31 : :
32 : :
33 : 97876035 : expression::expression ():
34 : 97876035 : type (pe_unknown), tok (0)
35 : : {
36 : 97876035 : }
37 : :
38 : :
39 : 21315 : expression::~expression ()
40 : : {
41 [ - + ]: 21315 : }
42 : :
43 : :
44 : 30958875 : statement::statement ():
45 : 30958875 : tok (0)
46 : : {
47 : 30958875 : }
48 : :
49 : :
50 : 265736 : statement::statement (const token* tok):
51 : 265736 : tok (tok)
52 : : {
53 : 265736 : }
54 : :
55 : :
56 : 265736 : null_statement::null_statement (const token* tok):
57 : 265736 : statement(tok)
58 : : {
59 : 265736 : }
60 : :
61 : :
62 : 12 : statement::~statement ()
63 : : {
64 [ - + ]: 12 : }
65 : :
66 : :
67 : 38834141 : symbol::symbol ():
68 [ + - ]: 38834141 : referent (0)
69 : : {
70 : 38834141 : }
71 : :
72 : :
73 : 1087061 : arrayindex::arrayindex ():
74 [ + - ]: 1087061 : base (0)
75 : : {
76 : 1087061 : }
77 : :
78 : :
79 : 9969890 : functioncall::functioncall ():
80 [ + - ][ + - ]: 9969890 : referent (0)
81 : : {
82 : 9969890 : }
83 : :
84 : :
85 : 3112724 : symboldecl::symboldecl ():
86 : : tok (0), systemtap_v_conditional (0),
87 : 3112724 : type (pe_unknown)
88 : : {
89 : 3112724 : }
90 : :
91 : :
92 : 0 : symboldecl::~symboldecl ()
93 : : {
94 [ # # ]: 0 : }
95 : :
96 : 0 : probe_point::probe_point (std::vector<component*> const & comps):
97 : : components(comps), optional (false), sufficient (false),
98 : 0 : condition (0)
99 : : {
100 : 0 : }
101 : :
102 : : // NB: shallow-copy of compoonents & condition!
103 : 575697 : probe_point::probe_point (const probe_point& pp):
104 : : components(pp.components), optional (pp.optional), sufficient (pp.sufficient),
105 : 575697 : condition (pp.condition)
106 : : {
107 : 575697 : }
108 : :
109 : :
110 : 11005308 : probe_point::probe_point ():
111 : 11005308 : optional (false), sufficient (false), condition (0)
112 : : {
113 : 11005308 : }
114 : :
115 : :
116 : : unsigned probe::last_probeidx = 0;
117 : :
118 : 4779624 : probe::probe ():
119 [ + - ][ + - ]: 4779624 : body (0), tok (0), systemtap_v_conditional (0), privileged (false)
[ + - ]
120 : : {
121 [ + - ][ + - ]: 4779624 : this->name = string ("probe_") + lex_cast(last_probeidx ++);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
122 : 4779624 : }
123 : :
124 : :
125 : : // Copy constructor, but with overriding probe-point. To be used when
126 : : // mapping script-level probe points to another one, early during pass
127 : : // 2. There should be no symbol resolution done yet.
128 [ + - ][ + - ]: 15 : probe::probe(const probe& p, probe_point* l)
[ + - ]
129 : : {
130 [ + - ][ + - ]: 15 : this->name = string ("probe_") + lex_cast(last_probeidx ++);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
131 : 15 : this->tok = p.tok;
132 [ + - ]: 15 : this->locations.push_back(l);
133 : 15 : this->body = p.body; // NB: not needed to be copied yet; a later derived_probe will
134 : 15 : this->privileged = p.privileged;
135 : 15 : this->systemtap_v_conditional = p.systemtap_v_conditional;
136 [ - + ]: 15 : assert (p.locals.size() == 0);
137 [ - + ]: 15 : assert (p.unused_locals.size() == 0);
138 : 15 : }
139 : :
140 : :
141 : 29782410 : probe_point::component::component ():
142 : 29782410 : arg (0), tok(0)
143 : : {
144 : 29782410 : }
145 : :
146 : :
147 : 919557 : probe_point::component::component (std::string const & f, literal * a):
148 : 919557 : functor(f), arg(a), tok(0)
149 : : {
150 : 919557 : }
151 : :
152 : :
153 : 1653251 : vardecl::vardecl ():
154 [ + - ]: 1653251 : arity_tok(0), arity (-1), maxsize(0), init(NULL), synthetic(false), wrap(false)
155 : : {
156 : 1653251 : }
157 : :
158 : :
159 : : void
160 : 808928 : vardecl::set_arity (int a, const token* t)
161 : : {
162 [ + + ]: 808928 : if (a < 0)
163 : 808924 : return;
164 : :
165 [ + + ][ + + ]: 808735 : if (a == 0 && maxsize > 0)
166 [ + - ][ + - ]: 1 : throw semantic_error (_("inconsistent arity"), tok);
167 : :
168 [ + + ][ + + ]: 808734 : if (arity != a && arity >= 0)
169 : : {
170 : 3 : semantic_error err (_F("inconsistent arity (%s vs %d)",
171 [ + - ][ + - ]: 3 : lex_cast(arity).c_str(), a), t?:tok);
[ + - ][ - + ]
[ + - ][ + - ]
[ + - ]
172 [ + - ]: 3 : if (arity_tok)
173 : 3 : err.chain = new semantic_error (_F("arity %s first inferred here",
174 [ + - ][ + - ]: 3 : lex_cast(arity).c_str()), arity_tok);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
175 [ + - ]: 3 : throw err;
176 : : }
177 : :
178 [ + + ]: 808731 : if (arity != a)
179 : : {
180 : 252014 : arity_tok = t;
181 : 252014 : arity = a;
182 : 252014 : index_types.resize (arity);
183 [ + + ]: 256845 : for (int i=0; i<arity; i++)
184 : 4831 : index_types[i] = pe_unknown;
185 : : }
186 : : }
187 : :
188 : : bool
189 : 28220 : vardecl::compatible_arity (int a)
190 : : {
191 [ + - ][ + + ]: 28220 : if (a == 0 && maxsize > 0)
192 : 2 : return false;
193 [ - + ][ # # ]: 28218 : if (arity == -1 || a == -1)
194 : 28218 : return true;
195 : 28220 : return arity == a;
196 : : }
197 : :
198 : :
199 : 1459473 : functiondecl::functiondecl ():
200 [ + - ][ + - ]: 1459473 : body (0), synthetic (false), mangle_oldstyle (false)
[ + - ]
201 : : {
202 : 1459473 : }
203 : :
204 : : void
205 : 185658 : functiondecl::join (systemtap_session& s)
206 : : {
207 [ - + ]: 185658 : if (!synthetic)
208 [ # # ][ # # ]: 0 : throw semantic_error (_("internal error, joining a non-synthetic function"), tok);
209 [ + - ][ + - ]: 185658 : if (!s.functions.insert (make_pair (name, this)).second)
[ + - ][ + - ]
[ + - ][ - + ]
210 : 0 : throw semantic_error (_F("synthetic function '%s' conflicts with an existing function",
211 [ # # ][ # # ]: 0 : name.c_str()), tok);
[ # # ]
212 [ + - ]: 185658 : tok->location.file->functions.push_back (this);
213 : 185658 : }
214 : :
215 : :
216 : 8215686 : literal_number::literal_number (int64_t v, bool hex)
217 : : {
218 : 8215686 : value = v;
219 : 8215686 : print_hex = hex;
220 : 8215686 : type = pe_long;
221 : 8215686 : }
222 : :
223 : :
224 [ + - ]: 13312353 : literal_string::literal_string (const string& v)
225 : : {
226 [ + - ]: 13312353 : value = v;
227 : 13312353 : type = pe_string;
228 : 13312353 : }
229 : :
230 : :
231 : : ostream&
232 : 351051 : operator << (ostream& o, const exp_type& e)
233 : : {
234 [ + + + + : 351051 : switch (e)
- ]
235 : : {
236 : 1975 : case pe_unknown: o << "unknown"; break;
237 : 247505 : case pe_long: o << "long"; break;
238 : 101340 : case pe_string: o << "string"; break;
239 : 231 : case pe_stats: o << "stats"; break;
240 : 0 : default: o << "???"; break;
241 : : }
242 : 351051 : return o;
243 : : }
244 : :
245 : :
246 : : void
247 : 25779 : target_symbol::assert_no_components(const std::string& tapset, bool pretty_ok)
248 : : {
249 [ + + ]: 25779 : if (components.empty())
250 : 24374 : return;
251 : :
252 [ + + + - ]: 1405 : switch (components[0].type)
253 : : {
254 : : case comp_literal_array_index:
255 : : case comp_expression_array_index:
256 : 4 : throw semantic_error(_F("%s variable '%s' may not be used as array",
257 [ + - ][ + - ]: 4 : tapset.c_str(), name.c_str()), components[0].tok);
[ + - ][ + - ]
258 : : case comp_struct_member:
259 : 4 : throw semantic_error(_F("%s variable '%s' may not be used as a structure",
260 [ + - ][ + - ]: 4 : tapset.c_str(), name.c_str()), components[0].tok);
[ + - ][ + - ]
261 : : case comp_pretty_print:
262 [ - + ]: 1397 : if (!pretty_ok)
263 : 0 : throw semantic_error(_F("%s variable '%s' may not be pretty-printed",
264 [ # # ][ # # ]: 0 : tapset.c_str(), name.c_str()), components[0].tok);
[ # # ][ # # ]
265 : 1397 : return;
266 : : default:
267 : 0 : throw semantic_error (_F("invalid use of %s variable '%s'",
268 [ # # ][ # # ]: 25771 : tapset.c_str(), name.c_str()), components[0].tok);
[ # # ][ # # ]
269 : : }
270 : : }
271 : :
272 : :
273 : 36237 : void target_symbol::chain (const semantic_error &er)
274 : : {
275 [ + - ]: 36237 : semantic_error* e = new semantic_error(er);
276 [ + + ]: 36237 : if (!e->tok1)
277 : 354 : e->tok1 = this->tok;
278 [ - + ]: 36237 : assert (e->chain == 0);
279 : 36237 : e->chain = this->saved_conversion_error;
280 : 36237 : this->saved_conversion_error = e;
281 : 36237 : }
282 : :
283 : 353611 : string target_symbol::sym_name ()
284 : : {
285 [ + + ]: 353611 : if (name == "@var")
286 : : {
287 [ - + ]: 1 : if (cu_name == "")
288 : 0 : return target_name;
289 : : else
290 : 1 : return target_name.substr(0, target_name.length() - cu_name.length() - 1);
291 : : }
292 : : else
293 : 353611 : return name.substr(1);
294 : : }
295 : :
296 : : // ------------------------------------------------------------------------
297 : : // parse tree printing
298 : :
299 : 3233197 : ostream& operator << (ostream& o, const expression& k)
300 : : {
301 : 3233197 : k.print (o);
302 : 3233197 : return o;
303 : : }
304 : :
305 : :
306 : 1149779 : void literal_string::print (ostream& o) const
307 : : {
308 : 1149779 : o << '"';
309 [ + + ]: 23265795 : for (unsigned i=0; i<value.size(); i++)
310 [ + + ]: 22116016 : if (value[i] == '"') // or other escapeworthy characters?
311 : 188 : o << '\\' << '"';
312 : : else
313 : 22115828 : o << value[i];
314 : 1149779 : o << '"';
315 : 1149779 : }
316 : :
317 : :
318 : 312961 : void literal_number::print (ostream& o) const
319 : : {
320 [ + + ]: 312961 : if (print_hex)
321 : 78 : o << hex << showbase;
322 : 312961 : o << value;
323 [ + + ]: 312961 : if (print_hex)
324 : 78 : o << dec << noshowbase;
325 : 312961 : }
326 : :
327 : :
328 : 22071 : void embedded_expr::print (ostream& o) const
329 : : {
330 : 22071 : o << "%{ " << code << " %}";
331 : 22071 : }
332 : :
333 : :
334 : 501417 : void binary_expression::print (ostream& o) const
335 : : {
336 : 501417 : o << "(" << *left << ") "
337 : 501417 : << op
338 : 501417 : << " (" << *right << ")";
339 : 501417 : }
340 : :
341 : :
342 : 9925 : void unary_expression::print (ostream& o) const
343 : : {
344 : 9925 : o << op << '(' << *operand << ")";
345 : 9925 : }
346 : :
347 : 1333 : void array_in::print (ostream& o) const
348 : : {
349 : 1333 : o << "[";
350 [ + + ]: 3593 : for (unsigned i=0; i<operand->indexes.size(); i++)
351 : : {
352 [ + + ]: 2260 : if (i > 0) o << ", ";
353 : 2260 : operand->indexes[i]->print (o);
354 : : }
355 : 1333 : o << "] in ";
356 : 1333 : operand->base->print (o);
357 : 1333 : }
358 : :
359 : 49449 : void post_crement::print (ostream& o) const
360 : : {
361 : 49449 : o << '(' << *operand << ")" << op;
362 : 49449 : }
363 : :
364 : :
365 : 1183 : void ternary_expression::print (ostream& o) const
366 : : {
367 : 1183 : o << "(" << *cond << ")?("
368 : 1183 : << *truevalue << "):("
369 : 1183 : << *falsevalue << ")";
370 : 1183 : }
371 : :
372 : :
373 : 934870 : void symbol::print (ostream& o) const
374 : : {
375 : 934870 : o << name;
376 : 934870 : }
377 : :
378 : :
379 : 2181 : void target_symbol::component::print (ostream& o) const
380 : : {
381 [ + + + - ]: 2181 : switch (type)
382 : : {
383 : : case comp_pretty_print:
384 : : case comp_struct_member:
385 : 2120 : o << "->" << member;
386 : 2120 : break;
387 : : case comp_literal_array_index:
388 : 46 : o << '[' << num_index << ']';
389 : 46 : break;
390 : : case comp_expression_array_index:
391 : 15 : o << '[' << *expr_index << ']';
392 : 15 : break;
393 : : }
394 : 2181 : }
395 : :
396 : :
397 : 2181 : std::ostream& operator << (std::ostream& o, const target_symbol::component& c)
398 : : {
399 : 2181 : c.print (o);
400 : 2181 : return o;
401 : : }
402 : :
403 : :
404 : 6672 : void target_symbol::print (ostream& o) const
405 : : {
406 [ + + ]: 6672 : if (addressof)
407 : 29 : o << "&";
408 : 6672 : o << name;
409 [ - + ]: 6672 : if (name == "@var")
410 : 0 : o << "(\"" << target_name << "\")";
411 [ + + ]: 8227 : for (unsigned i = 0; i < components.size(); ++i)
412 : 1555 : o << components[i];
413 : 6672 : }
414 : :
415 : :
416 : 521 : void cast_op::print (ostream& o) const
417 : : {
418 [ + + ]: 521 : if (addressof)
419 : 68 : o << "&";
420 : 521 : o << name << '(' << *operand;
421 [ + - ]: 521 : o << ", " << lex_cast_qstring (type_name);
422 [ + + ]: 521 : if (module.length() > 0)
423 [ + - ]: 225 : o << ", " << lex_cast_qstring (module);
424 : 521 : o << ')';
425 [ + + ]: 1147 : for (unsigned i = 0; i < components.size(); ++i)
426 : 626 : o << components[i];
427 : 521 : }
428 : :
429 : :
430 : 380 : void defined_op::print (ostream& o) const
431 : : {
432 : 380 : o << "@defined(" << *operand << ")";
433 : 380 : }
434 : :
435 : :
436 : 37 : void entry_op::print (ostream& o) const
437 : : {
438 : 37 : o << "@entry(" << *operand << ")";
439 : 37 : }
440 : :
441 : :
442 : 0 : void perf_op::print (ostream& o) const
443 : : {
444 : 0 : o << "@perf(" << *operand << ")";
445 : 0 : }
446 : :
447 : :
448 : 50510 : void vardecl::print (ostream& o) const
449 : : {
450 : 50510 : o << name;
451 [ + + ]: 50510 : if(wrap)
452 : 7 : o << "%";
453 [ + + ]: 50510 : if (maxsize > 0)
454 : 56 : o << "[" << maxsize << "]";
455 [ + - ][ - + ]: 50510 : if (arity > 0 || index_types.size() > 0)
[ - + ]
456 : 0 : o << "[...]";
457 [ + + ]: 50510 : if (init)
458 : : {
459 : 30 : o << " = ";
460 : 30 : init->print(o);
461 : : }
462 : 50510 : }
463 : :
464 : :
465 : 115890 : void vardecl::printsig (ostream& o) const
466 : : {
467 : 115890 : o << name;
468 [ + + ]: 115890 : if(wrap)
469 : 10 : o << "%";
470 [ + + ]: 115890 : if (maxsize > 0)
471 : 74 : o << "[" << maxsize << "]";
472 : 115890 : o << ":" << type;
473 [ + + ]: 115890 : if (index_types.size() > 0)
474 : : {
475 : 3031 : o << " [";
476 [ + + ]: 7545 : for (unsigned i=0; i<index_types.size(); i++)
477 [ + + ]: 4514 : o << (i>0 ? ", " : "") << index_types[i];
478 : 3031 : o << "]";
479 : : }
480 : 115890 : }
481 : :
482 : :
483 : 682 : void functiondecl::print (ostream& o) const
484 : : {
485 : 682 : o << "function " << name << " (";
486 [ + + ]: 1330 : for (unsigned i=0; i<formal_args.size(); i++)
487 [ + + ]: 648 : o << (i>0 ? ", " : "") << *formal_args[i];
488 : 682 : o << ")" << endl;
489 : 682 : body->print(o);
490 : 682 : }
491 : :
492 : :
493 : 181086 : void functiondecl::printsig (ostream& o) const
494 : : {
495 : 181086 : o << name << ":" << type << " (";
496 [ + + ]: 230576 : for (unsigned i=0; i<formal_args.size(); i++)
497 [ + + ]: 49490 : o << (i>0 ? ", " : "")
498 : 49490 : << *formal_args[i]
499 : 49490 : << ":"
500 : 49490 : << formal_args[i]->type;
501 : 181086 : o << ")";
502 : 181086 : }
503 : :
504 : :
505 : 142199 : void arrayindex::print (ostream& o) const
506 : : {
507 : 142199 : base->print (o);
508 : 142199 : o << "[";
509 [ + + ]: 323002 : for (unsigned i=0; i<indexes.size(); i++)
510 [ + + ]: 180803 : o << (i>0 ? ", " : "") << *indexes[i];
511 : 142199 : o << "]";
512 : 142199 : }
513 : :
514 : :
515 : 490696 : void functioncall::print (ostream& o) const
516 : : {
517 : 490696 : o << function << "(";
518 [ + + ]: 680315 : for (unsigned i=0; i<args.size(); i++)
519 [ + + ]: 189619 : o << (i>0 ? ", " : "") << *args[i];
520 : 490696 : o << ")";
521 : 490696 : }
522 : :
523 : :
524 : : print_format*
525 : 39638586 : print_format::create(const token *t)
526 : : {
527 : : bool stream, format, delim, newline, _char;
528 : 39638586 : const char *n = t->content.c_str();
529 : :
530 : 39638586 : stream = true;
531 : 39638586 : format = delim = newline = _char = false;
532 : :
533 [ + + ]: 39638586 : if (strcmp(n, "print_char") == 0)
534 : 20 : _char = true;
535 : : else
536 : : {
537 [ + + ]: 39638566 : if (*n == 's')
538 : : {
539 : 4370546 : stream = false;
540 : 4370546 : ++n;
541 : : }
542 : :
543 [ + + ]: 39638566 : if (0 != strncmp(n, "print", 5))
544 : 37438223 : return NULL;
545 : 2200343 : n += 5;
546 : :
547 [ + + ]: 2200343 : if (*n == 'f')
548 : : {
549 : 2068209 : format = true;
550 : 2068209 : ++n;
551 : : }
552 : : else
553 : : {
554 [ + + ]: 132134 : if (*n == 'd')
555 : : {
556 : 32 : delim = true;
557 : 32 : ++n;
558 : : }
559 : :
560 [ + + ][ + - ]: 132134 : if (*n == 'l' && *(n+1) == 'n')
561 : : {
562 : 1132 : newline = true;
563 : 1132 : n += 2;
564 : : }
565 : : }
566 : :
567 [ + + ]: 2200343 : if (*n != '\0')
568 : 8752 : return NULL;
569 : : }
570 : :
571 [ + - ]: 2191611 : print_format *pf = new print_format(stream, format, delim, newline, _char);
572 : 2191611 : pf->tok = t;
573 : 39638586 : return pf;
574 : : }
575 : :
576 : :
577 : : string
578 : 12703 : print_format::components_to_string(vector<format_component> const & components)
579 : : {
580 [ + - ]: 12703 : ostringstream oss;
581 : :
582 [ + - ][ + - ]: 128020 : for (vector<format_component>::const_iterator i = components.begin();
[ + + ]
583 [ + - ]: 64010 : i != components.end(); ++i)
584 : : {
585 : :
586 [ - + ]: 51307 : assert (i->type != conv_unspecified);
587 : :
588 [ + + ]: 51307 : if (i->type == conv_literal)
589 : : {
590 [ + - ][ - + ]: 25185 : assert(!i->literal_string.empty());
591 [ + - ][ + - ]: 351388 : for (string::const_iterator j = i->literal_string.begin();
[ + + ]
592 [ + - ]: 175694 : j != i->literal_string.end(); ++j)
593 : : {
594 : : // See also: c_unparser::visit_literal_string and lex_cast_qstring
595 [ + + ]: 150509 : if (*j == '%')
596 [ + - ]: 16 : oss << '%';
597 [ + + ]: 150493 : else if(*j == '"')
598 [ + - ]: 476 : oss << '\\';
599 [ + - ]: 150509 : oss << *j;
600 : : }
601 : : }
602 : : else
603 : : {
604 [ + - ]: 26122 : oss << '%';
605 : :
606 [ + + ]: 26122 : if (i->test_flag (fmt_flag_zeropad))
607 [ + - ]: 113 : oss << '0';
608 : :
609 [ + + ]: 26122 : if (i->test_flag (fmt_flag_plus))
610 [ + - ]: 1 : oss << '+';
611 : :
612 [ + + ]: 26122 : if (i->test_flag (fmt_flag_space))
613 [ + - ]: 2 : oss << ' ';
614 : :
615 [ + + ]: 26122 : if (i->test_flag (fmt_flag_left))
616 [ + - ]: 277 : oss << '-';
617 : :
618 [ + + ]: 26122 : if (i->test_flag (fmt_flag_special))
619 [ + - ]: 8958 : oss << '#';
620 : :
621 [ + + ]: 26122 : if (i->widthtype == width_dynamic)
622 [ + - ]: 33 : oss << '*';
623 [ + + ][ + - ]: 26089 : else if (i->widthtype != width_unspecified && i->width > 0)
[ + + ]
624 [ + - ]: 998 : oss << i->width;
625 : :
626 [ + + ]: 26122 : if (i->prectype == prec_dynamic)
627 [ + - ]: 30 : oss << ".*";
628 [ + + ][ + - ]: 26092 : else if (i->prectype != prec_unspecified && i->precision > 0)
[ + + ]
629 [ + - ][ + - ]: 111 : oss << '.' << i->precision;
630 : :
631 [ + + + + : 26122 : switch (i->type)
+ + + - ]
632 : : {
633 : : case conv_binary:
634 [ + - ]: 107 : oss << "b";
635 : 107 : break;
636 : :
637 : : case conv_char:
638 [ + - ]: 57 : oss << "llc";
639 : 57 : break;
640 : :
641 : : case conv_number:
642 [ + + ]: 11489 : if (i->base == 16)
643 : : {
644 [ + + ]: 5490 : if (i->test_flag (fmt_flag_large))
645 [ + - ]: 25 : oss << "llX";
646 : : else
647 [ + - ]: 5465 : oss << "llx";
648 : : }
649 [ + + ]: 5999 : else if (i->base == 8)
650 [ + - ]: 134 : oss << "llo";
651 [ + + ]: 5865 : else if (i->test_flag (fmt_flag_sign))
652 [ + - ]: 5364 : oss << "lld";
653 : : else
654 [ + - ]: 501 : oss << "llu";
655 : 11489 : break;
656 : :
657 : : case conv_pointer:
658 [ + - ]: 3104 : oss << "p";
659 : 3104 : break;
660 : :
661 : : case conv_string:
662 [ + - ]: 11287 : oss << 's';
663 : 11287 : break;
664 : :
665 : : case conv_memory:
666 [ + - ]: 52 : oss << 'm';
667 : 52 : break;
668 : :
669 : : case conv_memory_hex:
670 [ + - ]: 26 : oss << 'M';
671 : 26 : break;
672 : :
673 : : default:
674 : 0 : break;
675 : : }
676 : : }
677 : : }
678 [ + - ][ + - ]: 12703 : return oss.str ();
679 : : }
680 : :
681 : : vector<print_format::format_component>
682 : 2084286 : print_format::string_to_components(string const & str)
683 : : {
684 [ + - ]: 2084286 : format_component curr;
685 [ + - ]: 2084286 : vector<format_component> res;
686 : :
687 [ + - ]: 2084286 : curr.clear();
688 : :
689 [ + - ]: 2084286 : string::const_iterator i = str.begin();
690 : :
691 [ + - ][ + - ]: 17984467 : while (i != str.end())
[ + + ]
692 : : {
693 [ + + ]: 15900181 : if (*i != '%')
694 : : {
695 [ + + ][ - + ]: 10571521 : assert (curr.type == conv_unspecified || curr.type == conv_literal);
696 : 10571521 : curr.type = conv_literal;
697 [ + - ]: 10571521 : curr.literal_string += *i;
698 : 10571521 : ++i;
699 : 10571521 : continue;
700 : : }
701 [ + - ][ + - ]: 5328660 : else if (i+1 == str.end() || *(i+1) == '%')
[ + - ][ + - ]
[ + - ][ + + ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + +
# # # # #
# # # #
# ]
702 : : {
703 [ - + ]: 4358 : assert(*i == '%');
704 : : // *i == '%' and *(i+1) == '%'; append only one '%' to the literal string
705 [ + + ][ - + ]: 4358 : assert (curr.type == conv_unspecified || curr.type == conv_literal);
706 : 4358 : curr.type = conv_literal;
707 [ + - ]: 4358 : curr.literal_string += '%';
708 : 4358 : i += 2;
709 : 4358 : continue;
710 : : }
711 : : else
712 : : {
713 [ - + ]: 5324302 : assert(*i == '%');
714 [ + + ]: 5324302 : if (curr.type != conv_unspecified)
715 : : {
716 : : // Flush any component we were previously accumulating
717 [ - + ]: 3491280 : assert (curr.type == conv_literal);
718 [ + - ]: 3491280 : res.push_back(curr);
719 [ + - ]: 3491280 : curr.clear();
720 : : }
721 : : }
722 : 5324302 : ++i;
723 : :
724 [ + - ][ + - ]: 5324302 : if (i == str.end())
[ - + ]
725 : 0 : break;
726 : :
727 : : // Now we are definitely parsing a conversion.
728 : : // Begin by parsing flags (which are optional).
729 : :
730 [ + + + + : 5324302 : switch (*i)
+ + ]
731 : : {
732 : : case '0':
733 : 43373 : curr.set_flag (fmt_flag_zeropad);
734 : 43373 : ++i;
735 : 43373 : break;
736 : :
737 : : case '+':
738 : 3 : curr.set_flag (fmt_flag_plus);
739 : 3 : ++i;
740 : 3 : break;
741 : :
742 : : case '-':
743 : 2842 : curr.set_flag (fmt_flag_left);
744 : 2842 : ++i;
745 : 2842 : break;
746 : :
747 : : case ' ':
748 : 6 : curr.set_flag (fmt_flag_space);
749 : 6 : ++i;
750 : 6 : break;
751 : :
752 : : case '#':
753 : 109296 : curr.set_flag (fmt_flag_special);
754 : 109296 : ++i;
755 : 109296 : break;
756 : :
757 : : default:
758 : 5168782 : break;
759 : : }
760 : :
761 [ + - ][ + - ]: 5324302 : if (i == str.end())
[ - + ]
762 : 0 : break;
763 : :
764 : : // Parse optional width
765 [ + + ]: 5324302 : if (*i == '*')
766 : : {
767 : 2217 : curr.widthtype = width_dynamic;
768 : 2217 : ++i;
769 : : }
770 [ + + ]: 5322085 : else if (isdigit(*i))
771 : : {
772 : 54502 : curr.widthtype = width_static;
773 : 54502 : curr.width = 0;
774 [ + - + + ]: 167607 : do
[ + + ]
775 : : {
776 : 55869 : curr.width *= 10;
777 : 55869 : curr.width += (*i - '0');
778 : 55869 : ++i;
779 : : }
780 [ + - ][ + - ]: 167607 : while (i != str.end() && isdigit(*i));
[ + - ][ # # ]
781 : : }
782 : :
783 [ + - ][ + - ]: 5324302 : if (i == str.end())
[ - + ]
784 : 0 : break;
785 : :
786 : : // Parse optional precision
787 [ + + ]: 5324302 : if (*i == '.')
788 : : {
789 : 4582 : ++i;
790 [ + - ][ + - ]: 4582 : if (i == str.end())
[ - + ]
791 : 0 : break;
792 [ + + ]: 4582 : if (*i == '*')
793 : : {
794 : 58 : curr.prectype = prec_dynamic;
795 : 58 : ++i;
796 : : }
797 [ + - ]: 4524 : else if (isdigit(*i))
798 : : {
799 : 4524 : curr.prectype = prec_static;
800 : 4524 : curr.precision = 0;
801 [ + - + + ]: 13722 : do
[ + + ]
802 : : {
803 : 4574 : curr.precision *= 10;
804 : 4574 : curr.precision += (*i - '0');
805 : 4574 : ++i;
806 : : }
807 [ + - ][ + - ]: 13722 : while (i != str.end() && isdigit(*i));
[ + - ][ # # ]
808 : : }
809 : : }
810 : :
811 [ + - ][ + - ]: 5324302 : if (i == str.end())
[ - + ]
812 : 0 : break;
813 : :
814 : : // Parse the type modifier
815 [ + + ]: 5324302 : switch (*i)
816 : : {
817 : : case 'l':
818 : 240 : ++i;
819 : 240 : break;
820 : : }
821 : :
822 [ + - ][ + - ]: 5324302 : if (i == str.end())
[ - + ]
823 : 0 : break;
824 : :
825 : : // Parse the actual conversion specifier (bcsmdioupxXn)
826 [ + + + + : 5324302 : switch (*i)
+ + + + +
+ + - ]
827 : : {
828 : : // Valid conversion types
829 : : case 'b':
830 : 277 : curr.type = conv_binary;
831 : 277 : break;
832 : :
833 : : case 'c':
834 : 324 : curr.type = conv_char;
835 : 324 : break;
836 : :
837 : : case 's':
838 : 1466884 : curr.type = conv_string;
839 : 1466884 : break;
840 : :
841 : : case 'm':
842 : 144 : curr.type = conv_memory;
843 : 144 : break;
844 : :
845 : : case 'M':
846 : 78 : curr.type = conv_memory_hex;
847 : 78 : break;
848 : :
849 : : case 'd':
850 : : case 'i':
851 : 2419634 : curr.set_flag (fmt_flag_sign);
852 : : case 'u':
853 : 2433563 : curr.type = conv_number;
854 : 2433563 : curr.base = 10;
855 : 2433563 : break;
856 : :
857 : : case 'o':
858 : 45529 : curr.type = conv_number;
859 : 45529 : curr.base = 8;
860 : 45529 : break;
861 : :
862 : : case 'X':
863 : 71 : curr.set_flag (fmt_flag_large);
864 : : case 'x':
865 : 191861 : curr.type = conv_number;
866 : 191861 : curr.base = 16;
867 : 191861 : break;
868 : :
869 : : case 'p':
870 : : // Since stap 1.3, %p == %#x.
871 : 1185642 : curr.set_flag (fmt_flag_special);
872 : 1185642 : curr.type = conv_pointer;
873 : 1185642 : curr.base = 16;
874 : : // Oddness for stap < 1.3 is handled in translation
875 : 1185642 : break;
876 : :
877 : : default:
878 : 0 : break;
879 : : }
880 : :
881 [ - + ]: 5324302 : if (curr.type == conv_unspecified)
882 [ # # ][ # # ]: 0 : throw parse_error(_("invalid or missing conversion specifier"));
883 : :
884 : 5324302 : ++i;
885 [ + - ]: 5324302 : res.push_back(curr);
886 [ + - ]: 5324302 : curr.clear();
887 : : }
888 : :
889 : : // If there's a remaining partly-composed conversion, fail.
890 [ + - ][ + + ]: 2084286 : if (!curr.is_empty())
891 : : {
892 [ + - ]: 98810 : if (curr.type == conv_literal)
893 [ + - ]: 98810 : res.push_back(curr);
894 : : else
895 [ # # ][ # # ]: 0 : throw parse_error(_("trailing incomplete print format conversion"));
896 : : }
897 : :
898 [ + - ]: 2084286 : return res;
899 : : }
900 : :
901 : :
902 : 204604 : void print_format::print (ostream& o) const
903 : : {
904 : 204604 : o << tok->content << "(";
905 [ + + ]: 204604 : if (print_with_format)
906 [ + - ]: 170612 : o << lex_cast_qstring (raw_components);
907 [ + + ]: 204604 : if (print_with_delim)
908 [ + - ]: 84 : o << lex_cast_qstring (delimiter.literal_string);
909 [ + + ]: 204604 : if (hist)
910 : 290 : hist->print(o);
911 [ + - ][ + - ]: 1294320 : for (vector<expression*>::const_iterator i = args.begin();
[ + + ]
912 [ + - ]: 647160 : i != args.end(); ++i)
913 : : {
914 [ + - ][ + - ]: 442556 : if (i != args.begin() || print_with_format || print_with_delim)
[ + + ][ + + ]
[ + + ][ + - ]
[ + + # # ]
915 [ + - ]: 408938 : o << ", ";
916 [ + - ]: 442556 : (*i)->print(o);
917 : : }
918 : 204604 : o << ")";
919 : 204604 : }
920 : :
921 : 1992 : void stat_op::print (ostream& o) const
922 : : {
923 : 1992 : o << '@';
924 [ + + + + : 1992 : switch (ctype)
+ - - ]
925 : : {
926 : : case sc_average:
927 : 301 : o << "avg(";
928 : 301 : break;
929 : :
930 : : case sc_count:
931 : 816 : o << "count(";
932 : 816 : break;
933 : :
934 : : case sc_sum:
935 : 336 : o << "sum(";
936 : 336 : break;
937 : :
938 : : case sc_min:
939 : 268 : o << "min(";
940 : 268 : break;
941 : :
942 : : case sc_max:
943 : 271 : o << "max(";
944 : 271 : break;
945 : :
946 : : case sc_none:
947 : 0 : assert (0); // should not happen, as sc_none is only used in foreach sorts
948 : : break;
949 : : }
950 : 1992 : stat->print(o);
951 : 1992 : o << ")";
952 : 1992 : }
953 : :
954 : : void
955 : 461 : hist_op::print (ostream& o) const
956 : : {
957 : 461 : o << '@';
958 [ + + - ]: 461 : switch (htype)
959 : : {
960 : : case hist_linear:
961 [ - + ]: 168 : assert(params.size() == 3);
962 : 168 : o << "hist_linear(";
963 : 168 : stat->print(o);
964 [ + + ]: 672 : for (size_t i = 0; i < params.size(); ++i)
965 : : {
966 : 504 : o << ", " << params[i];
967 : : }
968 : 168 : o << ")";
969 : 168 : break;
970 : :
971 : : case hist_log:
972 [ - + ]: 293 : assert(params.size() == 0);
973 : 293 : o << "hist_log(";
974 : 293 : stat->print(o);
975 : 293 : o << ")";
976 : 293 : break;
977 : : }
978 : 461 : }
979 : :
980 : 866903 : ostream& operator << (ostream& o, const statement& k)
981 : : {
982 : 866903 : k.print (o);
983 : 866903 : return o;
984 : : }
985 : :
986 : :
987 : 164524 : void embeddedcode::print (ostream &o) const
988 : : {
989 : 164524 : o << "%{";
990 : 164524 : o << code;
991 : 164524 : o << "%}";
992 : 164524 : }
993 : :
994 : 147100 : void block::print (ostream& o) const
995 : : {
996 : 147100 : o << "{" << endl;
997 [ + + ]: 741355 : for (unsigned i=0; i<statements.size(); i++)
998 : 594255 : o << *statements [i] << endl;
999 : 147100 : o << "}";
1000 : 147100 : }
1001 : :
1002 [ + - ]: 66193 : block::block (statement* car, statement* cdr)
1003 : : {
1004 [ + - ]: 66193 : statements.push_back(car);
1005 [ + - ]: 66193 : statements.push_back(cdr);
1006 : 66193 : this->tok = car->tok;
1007 : 66193 : }
1008 : :
1009 : :
1010 : :
1011 : 5159 : void try_block::print (ostream& o) const
1012 : : {
1013 : 5159 : o << "try {" << endl;
1014 [ + - ]: 5159 : if (try_block) o << *try_block << endl;
1015 : 5159 : o << "} catch ";
1016 [ + + ]: 5159 : if (catch_error_var) o << "(" << *catch_error_var << ") ";
1017 : 5159 : o << "{" << endl;
1018 [ + + ]: 5159 : if (catch_block) o << *catch_block << endl;
1019 : 5159 : o << "}" << endl;
1020 : 5159 : }
1021 : :
1022 : :
1023 : 1136 : void for_loop::print (ostream& o) const
1024 : : {
1025 : 1136 : o << "for (";
1026 [ + + ]: 1136 : if (init) init->print (o);
1027 : 1136 : o << "; ";
1028 : 1136 : cond->print (o);
1029 : 1136 : o << "; ";
1030 [ + + ]: 1136 : if (incr) incr->print (o);
1031 : 1136 : o << ") ";
1032 : 1136 : block->print (o);
1033 : 1136 : }
1034 : :
1035 : :
1036 : 983 : void foreach_loop::print (ostream& o) const
1037 : : {
1038 : 983 : o << "foreach (";
1039 [ + + ]: 983 : if (value)
1040 : : {
1041 : 136 : value->print (o);
1042 : 136 : o << " = ";
1043 : : }
1044 : 983 : o << "[";
1045 [ + + ]: 3037 : for (unsigned i=0; i<indexes.size(); i++)
1046 : : {
1047 [ + + ]: 2054 : if (i > 0) o << ", ";
1048 : 2054 : indexes[i]->print (o);
1049 [ + + ][ + + ]: 2054 : if (sort_direction != 0 && sort_column == i+1)
1050 [ + + ]: 96 : o << (sort_direction > 0 ? "+" : "-");
1051 : : }
1052 : 983 : o << "] in ";
1053 : 983 : base->print (o);
1054 [ + + ][ + + ]: 983 : if (sort_direction != 0 && sort_column == 0)
1055 : : {
1056 [ + + + + : 470 : switch (sort_aggr)
+ + ]
1057 : : {
1058 : 6 : case sc_count: o << " @count"; break;
1059 : 6 : case sc_average: o << " @avg"; break;
1060 : 6 : case sc_min: o << " @min"; break;
1061 : 6 : case sc_max: o << " @max"; break;
1062 : 9 : case sc_sum: o << " @sum"; break;
1063 : : case sc_none:
1064 : : default:
1065 : : ;
1066 : : }
1067 : :
1068 [ + + ]: 470 : o << (sort_direction > 0 ? "+" : "-");
1069 : : }
1070 [ + + ]: 983 : if (limit)
1071 : : {
1072 : 152 : o << " limit ";
1073 : 152 : limit->print (o);
1074 : : }
1075 : 983 : o << ") ";
1076 : 983 : block->print (o);
1077 : 983 : }
1078 : :
1079 : :
1080 : 2773 : void null_statement::print (ostream& o) const
1081 : : {
1082 : 2773 : o << ";";
1083 : 2773 : }
1084 : :
1085 : :
1086 : 495664 : void expr_statement::print (ostream& o) const
1087 : : {
1088 : 495664 : o << *value;
1089 : 495664 : }
1090 : :
1091 : :
1092 : 102174 : void return_statement::print (ostream& o) const
1093 : : {
1094 : 102174 : o << "return " << *value;
1095 : 102174 : }
1096 : :
1097 : :
1098 : 7236 : void delete_statement::print (ostream& o) const
1099 : : {
1100 : 7236 : o << "delete " << *value;
1101 : 7236 : }
1102 : :
1103 : 10419 : void next_statement::print (ostream& o) const
1104 : : {
1105 : 10419 : o << "next";
1106 : 10419 : }
1107 : :
1108 : 534 : void break_statement::print (ostream& o) const
1109 : : {
1110 : 534 : o << "break";
1111 : 534 : }
1112 : :
1113 : 176 : void continue_statement::print (ostream& o) const
1114 : : {
1115 : 176 : o << "continue";
1116 : 176 : }
1117 : :
1118 : 229722 : void if_statement::print (ostream& o) const
1119 : : {
1120 : 229722 : o << "if (" << *condition << ") "
1121 : 229722 : << *thenblock << endl;
1122 [ + + ]: 229722 : if (elseblock)
1123 : 29306 : o << "else " << *elseblock << endl;
1124 : 229722 : }
1125 : :
1126 : :
1127 : 904 : void stapfile::print (ostream& o) const
1128 : : {
1129 : 904 : o << "# file " << name << endl;
1130 : :
1131 [ + + ]: 956 : for (unsigned i=0; i<embeds.size(); i++)
1132 : 52 : embeds[i]->print (o);
1133 : :
1134 [ + + ]: 1276 : for (unsigned i=0; i<globals.size(); i++)
1135 : : {
1136 : 372 : o << "global ";
1137 : 372 : globals[i]->print (o);
1138 : 372 : o << endl;
1139 : : }
1140 : :
1141 [ + + ]: 3090 : for (unsigned i=0; i<aliases.size(); i++)
1142 : : {
1143 : 2186 : aliases[i]->print (o);
1144 : 2186 : o << endl;
1145 : : }
1146 : :
1147 [ + + ]: 2046 : for (unsigned i=0; i<probes.size(); i++)
1148 : : {
1149 : 1142 : probes[i]->print (o);
1150 : 1142 : o << endl;
1151 : : }
1152 : :
1153 [ + + ]: 1586 : for (unsigned j = 0; j < functions.size(); j++)
1154 : : {
1155 : 682 : functions[j]->print (o);
1156 : 682 : o << endl;
1157 : : }
1158 : 904 : }
1159 : :
1160 : :
1161 : 3328 : void probe::print (ostream& o) const
1162 : : {
1163 : 3328 : o << "probe ";
1164 : 3328 : printsig (o);
1165 : 3328 : o << *body;
1166 : 3328 : }
1167 : :
1168 : :
1169 : 406809 : void probe::printsig (ostream& o) const
1170 : : {
1171 : 406809 : const probe_alias *alias = get_alias ();
1172 [ + + ]: 406809 : if (alias)
1173 : : {
1174 : 52421 : alias->printsig (o);
1175 : 406809 : return;
1176 : : }
1177 : :
1178 [ + + ]: 723442 : for (unsigned i=0; i<locations.size(); i++)
1179 : : {
1180 [ + + ]: 369054 : if (i > 0) o << ",";
1181 : 369054 : locations[i]->print (o);
1182 : : }
1183 : : }
1184 : :
1185 : :
1186 : : void
1187 : 75390 : probe::collect_derivation_chain (std::vector<probe*> &probes_list)
1188 : : {
1189 [ + - ]: 75390 : probes_list.push_back(this);
1190 : 75390 : }
1191 : :
1192 : :
1193 : 1001348 : void probe_point::print (ostream& o, bool print_extras) const
1194 : : {
1195 [ + + ]: 3540360 : for (unsigned i=0; i<components.size(); i++)
1196 : : {
1197 [ + + ]: 2539012 : if (i>0) o << ".";
1198 : 2539012 : probe_point::component* c = components[i];
1199 : 2539012 : o << c->functor;
1200 [ + + ]: 2539012 : if (c->arg)
1201 : 952870 : o << "(" << *c->arg << ")";
1202 : : }
1203 [ + + ]: 1001348 : if (!print_extras)
1204 : 1001348 : return;
1205 [ + + ]: 946948 : if (sufficient)
1206 : 4378 : o << "!";
1207 [ + + ]: 942570 : else if (optional) // sufficient implies optional
1208 : 162508 : o << "?";
1209 [ + + ]: 946948 : if (condition)
1210 : 109 : o<< " if (" << *condition << ")";
1211 : : }
1212 : :
1213 : 54400 : string probe_point::str (bool print_extras) const
1214 : : {
1215 [ + - ]: 54400 : ostringstream o;
1216 [ + - ]: 54400 : print(o, print_extras);
1217 [ + - ][ + - ]: 54400 : return o.str();
1218 : : }
1219 : :
1220 : :
1221 : 4339470 : probe_alias::probe_alias(std::vector<probe_point*> const & aliases):
1222 [ + - ]: 4339470 : probe (), alias_names (aliases), epilogue_style(false)
1223 : : {
1224 : 4339470 : }
1225 : :
1226 : 54607 : void probe_alias::printsig (ostream& o) const
1227 : : {
1228 [ + + ]: 109214 : for (unsigned i=0; i<alias_names.size(); i++)
1229 : : {
1230 [ - + ]: 54607 : o << (i>0 ? " = " : "");
1231 : 54607 : alias_names[i]->print (o);
1232 : : }
1233 : 54607 : o << " = ";
1234 [ + + ]: 159848 : for (unsigned i=0; i<locations.size(); i++)
1235 : : {
1236 [ + + ]: 105241 : if (i > 0) o << ", ";
1237 : 105241 : locations[i]->print (o);
1238 : : }
1239 : 54607 : }
1240 : :
1241 : :
1242 : 67961 : ostream& operator << (ostream& o, const probe_point& k)
1243 : : {
1244 : 67961 : k.print (o);
1245 : 67961 : return o;
1246 : : }
1247 : :
1248 : :
1249 : 50138 : ostream& operator << (ostream& o, const symboldecl& k)
1250 : : {
1251 : 50138 : k.print (o);
1252 : 50138 : return o;
1253 : : }
1254 : :
1255 : :
1256 : :
1257 : : // ------------------------------------------------------------------------
1258 : : // visitors
1259 : :
1260 : :
1261 : : void
1262 : 9638018 : block::visit (visitor* u)
1263 : : {
1264 : 9638018 : u->visit_block (this);
1265 : 9637989 : }
1266 : :
1267 : :
1268 : : void
1269 : 70746 : try_block::visit (visitor* u)
1270 : : {
1271 : 70746 : u->visit_try_block (this);
1272 : 70746 : }
1273 : :
1274 : :
1275 : : void
1276 : 5242584 : embeddedcode::visit (visitor* u)
1277 : : {
1278 : 5242584 : u->visit_embeddedcode (this);
1279 : 5242575 : }
1280 : :
1281 : :
1282 : : void
1283 : 18012 : for_loop::visit (visitor* u)
1284 : : {
1285 : 18012 : u->visit_for_loop (this);
1286 : 18012 : }
1287 : :
1288 : : void
1289 : 13209 : foreach_loop::visit (visitor* u)
1290 : : {
1291 : 13209 : u->visit_foreach_loop (this);
1292 : 13209 : }
1293 : :
1294 : : void
1295 : 2126112 : null_statement::visit (visitor* u)
1296 : : {
1297 : 2126112 : u->visit_null_statement (this);
1298 : 2126112 : }
1299 : :
1300 : : void
1301 : 22303498 : expr_statement::visit (visitor* u)
1302 : : {
1303 : 22303498 : u->visit_expr_statement (this);
1304 : 22303260 : }
1305 : :
1306 : : void
1307 : 3264605 : return_statement::visit (visitor* u)
1308 : : {
1309 : 3264605 : u->visit_return_statement (this);
1310 : 3264598 : }
1311 : :
1312 : : void
1313 : 133670 : delete_statement::visit (visitor* u)
1314 : : {
1315 : 133670 : u->push_active_lvalue (this->value);
1316 : 133670 : u->visit_delete_statement (this);
1317 : 133669 : u->pop_active_lvalue ();
1318 : 133669 : }
1319 : :
1320 : : void
1321 : 8511610 : if_statement::visit (visitor* u)
1322 : : {
1323 : 8511610 : u->visit_if_statement (this);
1324 : 8511607 : }
1325 : :
1326 : : void
1327 : 187413 : next_statement::visit (visitor* u)
1328 : : {
1329 : 187413 : u->visit_next_statement (this);
1330 : 187413 : }
1331 : :
1332 : : void
1333 : 9659 : break_statement::visit (visitor* u)
1334 : : {
1335 : 9659 : u->visit_break_statement (this);
1336 : 9658 : }
1337 : :
1338 : : void
1339 : 1855 : continue_statement::visit (visitor* u)
1340 : : {
1341 : 1855 : u->visit_continue_statement (this);
1342 : 1854 : }
1343 : :
1344 : : void
1345 : 9199913 : literal_string::visit(visitor* u)
1346 : : {
1347 : 9199913 : u->visit_literal_string (this);
1348 : 9199913 : }
1349 : :
1350 : : void
1351 : 13406252 : literal_number::visit(visitor* u)
1352 : : {
1353 : 13406252 : u->visit_literal_number (this);
1354 : 13406251 : }
1355 : :
1356 : : void
1357 : 685446 : binary_expression::visit (visitor* u)
1358 : : {
1359 : 685446 : u->visit_binary_expression (this);
1360 : 685443 : }
1361 : :
1362 : : void
1363 : 377502 : embedded_expr::visit (visitor* u)
1364 : : {
1365 : 377502 : u->visit_embedded_expr (this);
1366 : 377502 : }
1367 : :
1368 : : void
1369 : 565576 : unary_expression::visit (visitor* u)
1370 : : {
1371 : 565576 : u->visit_unary_expression (this);
1372 : 565576 : }
1373 : :
1374 : : void
1375 : 61231 : pre_crement::visit (visitor* u)
1376 : : {
1377 : 61231 : u->push_active_lvalue (this->operand);
1378 : 61231 : u->visit_pre_crement (this);
1379 : 61229 : u->pop_active_lvalue ();
1380 : 61229 : }
1381 : :
1382 : : void
1383 : 2026789 : post_crement::visit (visitor* u)
1384 : : {
1385 : 2026789 : u->push_active_lvalue (this->operand);
1386 : 2026789 : u->visit_post_crement (this);
1387 : 2026788 : u->pop_active_lvalue ();
1388 : 2026788 : }
1389 : :
1390 : : void
1391 : 197123 : logical_or_expr::visit (visitor* u)
1392 : : {
1393 : 197123 : u->visit_logical_or_expr (this);
1394 : 197123 : }
1395 : :
1396 : : void
1397 : 273629 : logical_and_expr::visit (visitor* u)
1398 : : {
1399 : 273629 : u->visit_logical_and_expr (this);
1400 : 273629 : }
1401 : :
1402 : : void
1403 : 182891 : array_in::visit (visitor* u)
1404 : : {
1405 : 182891 : u->visit_array_in (this);
1406 : 182890 : }
1407 : :
1408 : : void
1409 : 1103 : regex_query::visit (visitor* u)
1410 : : {
1411 : 1103 : u->visit_regex_query (this);
1412 : 1103 : }
1413 : :
1414 : : void
1415 : 4529201 : comparison::visit (visitor* u)
1416 : : {
1417 : 4529201 : u->visit_comparison (this);
1418 : 4529200 : }
1419 : :
1420 : : void
1421 : 532987 : concatenation::visit (visitor* u)
1422 : : {
1423 : 532987 : u->visit_concatenation (this);
1424 : 532985 : }
1425 : :
1426 : : void
1427 : 115180 : ternary_expression::visit (visitor* u)
1428 : : {
1429 : 115180 : u->visit_ternary_expression (this);
1430 : 115180 : }
1431 : :
1432 : : void
1433 : 14566548 : assignment::visit (visitor* u)
1434 : : {
1435 : 14566548 : u->push_active_lvalue (this->left);
1436 : 14566548 : u->visit_assignment (this);
1437 : 14566353 : u->pop_active_lvalue ();
1438 : 14566353 : }
1439 : :
1440 : : void
1441 : 35186737 : symbol::visit (visitor* u)
1442 : : {
1443 : 35186737 : u->visit_symbol (this);
1444 : 35186734 : }
1445 : :
1446 : : void
1447 : 368810 : target_symbol::visit (visitor* u)
1448 : : {
1449 : 368810 : u->visit_target_symbol(this);
1450 : 368604 : }
1451 : :
1452 : : void
1453 : 25942 : target_symbol::visit_components (visitor* u)
1454 : : {
1455 [ + + ]: 32971 : for (unsigned i = 0; i < components.size(); ++i)
1456 [ + + ]: 7029 : if (components[i].type == comp_expression_array_index)
1457 : 5 : components[i].expr_index->visit (u);
1458 : 25942 : }
1459 : :
1460 : : void
1461 : 137031 : target_symbol::visit_components (update_visitor* u)
1462 : : {
1463 [ + + ]: 145923 : for (unsigned i = 0; i < components.size(); ++i)
1464 [ + + ]: 8892 : if (components[i].type == comp_expression_array_index)
1465 : 29 : u->replace (components[i].expr_index);
1466 : 137031 : }
1467 : :
1468 : : void
1469 : 12907 : cast_op::visit (visitor* u)
1470 : : {
1471 : 12907 : u->visit_cast_op(this);
1472 : 12907 : }
1473 : :
1474 : :
1475 : : void
1476 : 12044 : defined_op::visit (visitor* u)
1477 : : {
1478 : 12044 : u->visit_defined_op(this);
1479 : 12044 : }
1480 : :
1481 : :
1482 : : void
1483 : 2257 : entry_op::visit (visitor* u)
1484 : : {
1485 : 2257 : u->visit_entry_op(this);
1486 : 2254 : }
1487 : :
1488 : :
1489 : : void
1490 : 30 : perf_op::visit (visitor* u)
1491 : : {
1492 : 30 : u->visit_perf_op(this);
1493 : 28 : }
1494 : :
1495 : :
1496 : : void
1497 : 7898270 : arrayindex::visit (visitor* u)
1498 : : {
1499 : 7898270 : u->visit_arrayindex (this);
1500 : 7898264 : }
1501 : :
1502 : : void
1503 : 14757524 : functioncall::visit (visitor* u)
1504 : : {
1505 : 14757524 : u->visit_functioncall (this);
1506 : 14757387 : }
1507 : :
1508 : : void
1509 : 6399805 : print_format::visit (visitor *u)
1510 : : {
1511 : 6399805 : u->visit_print_format (this);
1512 : 6399775 : }
1513 : :
1514 : : void
1515 : 31148 : stat_op::visit (visitor *u)
1516 : : {
1517 : 31148 : u->visit_stat_op (this);
1518 : 31147 : }
1519 : :
1520 : : void
1521 : 3197 : hist_op::visit (visitor *u)
1522 : : {
1523 : 3197 : u->visit_hist_op (this);
1524 : 3197 : }
1525 : :
1526 : :
1527 : : bool
1528 : 433 : indexable::is_symbol(symbol *& sym_out)
1529 : : {
1530 : 433 : sym_out = NULL;
1531 : 433 : return false;
1532 : : }
1533 : :
1534 : : bool
1535 : 0 : indexable::is_hist_op(hist_op *& hist_out)
1536 : : {
1537 : 0 : hist_out = NULL;
1538 : 0 : return false;
1539 : : }
1540 : :
1541 : : bool
1542 : 6401068 : symbol::is_symbol(symbol *& sym_out)
1543 : : {
1544 : 6401068 : sym_out = this;
1545 : 6401068 : return true;
1546 : : }
1547 : :
1548 : : bool
1549 : 433 : hist_op::is_hist_op(hist_op *& hist_out)
1550 : : {
1551 : 433 : hist_out = this;
1552 : 433 : return true;
1553 : : }
1554 : :
1555 : : void
1556 : 6399646 : classify_indexable(indexable* ix,
1557 : : symbol *& array_out,
1558 : : hist_op *& hist_out)
1559 : : {
1560 : 6399646 : array_out = NULL;
1561 : 6399646 : hist_out = NULL;
1562 [ - + ]: 6399646 : assert(ix != NULL);
1563 [ + + ][ - + ]: 6399646 : if (!(ix->is_symbol (array_out) || ix->is_hist_op (hist_out)))
[ - + ]
1564 [ # # ][ # # ]: 0 : throw semantic_error(_("Expecting symbol or histogram operator"), ix->tok);
1565 [ + + ][ - + ]: 6399646 : if (!(hist_out || array_out))
1566 [ # # ][ # # ]: 0 : throw semantic_error(_("Failed to classify indexable"), ix->tok);
1567 : 6399646 : }
1568 : :
1569 : :
1570 : : // ------------------------------------------------------------------------
1571 : :
1572 : : bool
1573 : 312590 : visitor::is_active_lvalue(expression *e)
1574 : : {
1575 [ + + ]: 432747 : for (unsigned i = 0; i < active_lvalues.size(); ++i)
1576 : : {
1577 [ + + ]: 152993 : if (active_lvalues[i] == e)
1578 : 32836 : return true;
1579 : : }
1580 : 312590 : return false;
1581 : : }
1582 : :
1583 : : void
1584 : 16788238 : visitor::push_active_lvalue(expression *e)
1585 : : {
1586 : 16788238 : active_lvalues.push_back(e);
1587 : 16788238 : }
1588 : :
1589 : : void
1590 : 16788039 : visitor::pop_active_lvalue()
1591 : : {
1592 [ - + ]: 16788039 : assert(!active_lvalues.empty());
1593 : 16788039 : active_lvalues.pop_back();
1594 : 16788039 : }
1595 : :
1596 : :
1597 : :
1598 : : // ------------------------------------------------------------------------
1599 : :
1600 : : void
1601 : 4326429 : traversing_visitor::visit_block (block* s)
1602 : : {
1603 [ + + ]: 19745867 : for (unsigned i=0; i<s->statements.size(); i++)
1604 : 15419456 : s->statements[i]->visit (this);
1605 : 4326411 : }
1606 : :
1607 : : void
1608 : 18253 : traversing_visitor::visit_try_block (try_block* s)
1609 : : {
1610 [ + - ]: 18253 : if (s->try_block)
1611 : 18253 : s->try_block->visit (this);
1612 [ + + ]: 18253 : if (s->catch_error_var)
1613 : 27 : s->catch_error_var->visit (this);
1614 [ + + ]: 18253 : if (s->catch_block)
1615 : 18192 : s->catch_block->visit (this);
1616 : 18253 : }
1617 : :
1618 : : void
1619 : 907955 : traversing_visitor::visit_embeddedcode (embeddedcode*)
1620 : : {
1621 : 907955 : }
1622 : :
1623 : : void
1624 : 1324899 : traversing_visitor::visit_null_statement (null_statement*)
1625 : : {
1626 : 1324899 : }
1627 : :
1628 : : void
1629 : 13410228 : traversing_visitor::visit_expr_statement (expr_statement* s)
1630 : : {
1631 : 13410228 : s->value->visit (this);
1632 : 13410206 : }
1633 : :
1634 : : void
1635 : 4743923 : traversing_visitor::visit_if_statement (if_statement* s)
1636 : : {
1637 : 4743923 : s->condition->visit (this);
1638 : 4743922 : s->thenblock->visit (this);
1639 [ + + ]: 4743920 : if (s->elseblock)
1640 : 1043694 : s->elseblock->visit (this);
1641 : 4743920 : }
1642 : :
1643 : : void
1644 : 8651 : traversing_visitor::visit_for_loop (for_loop* s)
1645 : : {
1646 [ + + ]: 8651 : if (s->init) s->init->visit (this);
1647 : 8651 : s->cond->visit (this);
1648 [ + + ]: 8651 : if (s->incr) s->incr->visit (this);
1649 : 8651 : s->block->visit (this);
1650 : 8651 : }
1651 : :
1652 : : void
1653 : 2348 : traversing_visitor::visit_foreach_loop (foreach_loop* s)
1654 : : {
1655 : 2348 : s->base->visit(this);
1656 : :
1657 [ + + ]: 6535 : for (unsigned i=0; i<s->indexes.size(); i++)
1658 : 4187 : s->indexes[i]->visit (this);
1659 : :
1660 [ + + ]: 2348 : if (s->value)
1661 : 236 : s->value->visit (this);
1662 : :
1663 [ + + ]: 2348 : if (s->limit)
1664 : 422 : s->limit->visit (this);
1665 : :
1666 : 2348 : s->block->visit (this);
1667 : 2348 : }
1668 : :
1669 : : void
1670 : 2402008 : traversing_visitor::visit_return_statement (return_statement* s)
1671 : : {
1672 : 2402008 : s->value->visit (this);
1673 : 2402001 : }
1674 : :
1675 : : void
1676 : 58060 : traversing_visitor::visit_delete_statement (delete_statement* s)
1677 : : {
1678 : 58060 : s->value->visit (this);
1679 : 58060 : }
1680 : :
1681 : : void
1682 : 84858 : traversing_visitor::visit_next_statement (next_statement*)
1683 : : {
1684 : 84858 : }
1685 : :
1686 : : void
1687 : 5118 : traversing_visitor::visit_break_statement (break_statement*)
1688 : : {
1689 : 5118 : }
1690 : :
1691 : : void
1692 : 991 : traversing_visitor::visit_continue_statement (continue_statement*)
1693 : : {
1694 : 991 : }
1695 : :
1696 : : void
1697 : 7657932 : traversing_visitor::visit_literal_string (literal_string*)
1698 : : {
1699 : 7657932 : }
1700 : :
1701 : : void
1702 : 10681432 : traversing_visitor::visit_literal_number (literal_number*)
1703 : : {
1704 : 10681432 : }
1705 : :
1706 : : void
1707 : 97550 : traversing_visitor::visit_embedded_expr (embedded_expr*)
1708 : : {
1709 : 97550 : }
1710 : :
1711 : : void
1712 : 515241 : traversing_visitor::visit_binary_expression (binary_expression* e)
1713 : : {
1714 : 515241 : e->left->visit (this);
1715 : 515241 : e->right->visit (this);
1716 : 515241 : }
1717 : :
1718 : : void
1719 : 516278 : traversing_visitor::visit_unary_expression (unary_expression* e)
1720 : : {
1721 : 516278 : e->operand->visit (this);
1722 : 516278 : }
1723 : :
1724 : : void
1725 : 34407 : traversing_visitor::visit_pre_crement (pre_crement* e)
1726 : : {
1727 : 34407 : e->operand->visit (this);
1728 : 34407 : }
1729 : :
1730 : : void
1731 : 1075769 : traversing_visitor::visit_post_crement (post_crement* e)
1732 : : {
1733 : 1075769 : e->operand->visit (this);
1734 : 1075769 : }
1735 : :
1736 : :
1737 : : void
1738 : 177756 : traversing_visitor::visit_logical_or_expr (logical_or_expr* e)
1739 : : {
1740 : 177756 : e->left->visit (this);
1741 : 177756 : e->right->visit (this);
1742 : 177756 : }
1743 : :
1744 : : void
1745 : 237870 : traversing_visitor::visit_logical_and_expr (logical_and_expr* e)
1746 : : {
1747 : 237870 : e->left->visit (this);
1748 : 237870 : e->right->visit (this);
1749 : 237870 : }
1750 : :
1751 : : void
1752 : 169694 : traversing_visitor::visit_array_in (array_in* e)
1753 : : {
1754 : 169694 : e->operand->visit (this);
1755 : 169693 : }
1756 : :
1757 : : void
1758 : 639 : traversing_visitor::visit_regex_query (regex_query* e)
1759 : : {
1760 : 639 : e->left->visit (this);
1761 : 639 : e->right->visit (this); // TODOXXX do we need to traverse the literal in RHS?
1762 : 639 : }
1763 : :
1764 : : void
1765 : 3185740 : traversing_visitor::visit_comparison (comparison* e)
1766 : : {
1767 : 3185740 : e->left->visit (this);
1768 : 3185739 : e->right->visit (this);
1769 : 3185739 : }
1770 : :
1771 : : void
1772 : 410977 : traversing_visitor::visit_concatenation (concatenation* e)
1773 : : {
1774 : 410977 : e->left->visit (this);
1775 : 410975 : e->right->visit (this);
1776 : 410975 : }
1777 : :
1778 : : void
1779 : 82770 : traversing_visitor::visit_ternary_expression (ternary_expression* e)
1780 : : {
1781 : 82770 : e->cond->visit (this);
1782 : 82770 : e->truevalue->visit (this);
1783 : 82770 : e->falsevalue->visit (this);
1784 : 82770 : }
1785 : :
1786 : : void
1787 : 10411860 : traversing_visitor::visit_assignment (assignment* e)
1788 : : {
1789 : 10411860 : e->left->visit (this);
1790 : 10411856 : e->right->visit (this);
1791 : 10411854 : }
1792 : :
1793 : : void
1794 : 5647101 : traversing_visitor::visit_symbol (symbol*)
1795 : : {
1796 : 5647101 : }
1797 : :
1798 : : void
1799 : 22933 : traversing_visitor::visit_target_symbol (target_symbol* e)
1800 : : {
1801 : 22933 : e->visit_components (this);
1802 : 22933 : }
1803 : :
1804 : : void
1805 : 3009 : traversing_visitor::visit_cast_op (cast_op* e)
1806 : : {
1807 : 3009 : e->operand->visit (this);
1808 : 3009 : e->visit_components (this);
1809 : 3009 : }
1810 : :
1811 : : void
1812 : 55 : traversing_visitor::visit_defined_op (defined_op* e)
1813 : : {
1814 : 55 : e->operand->visit (this);
1815 : 55 : }
1816 : :
1817 : : void
1818 : 32 : traversing_visitor::visit_entry_op (entry_op* e)
1819 : : {
1820 : 32 : e->operand->visit (this);
1821 : 32 : }
1822 : :
1823 : :
1824 : : void
1825 : 9 : traversing_visitor::visit_perf_op (perf_op* e)
1826 : : {
1827 : 9 : e->operand->visit (this);
1828 : 9 : }
1829 : :
1830 : :
1831 : : void
1832 : 6483987 : traversing_visitor::visit_arrayindex (arrayindex* e)
1833 : : {
1834 [ + + ]: 13222580 : for (unsigned i=0; i<e->indexes.size(); i++)
1835 : 6738593 : e->indexes[i]->visit (this);
1836 : :
1837 : 6483987 : e->base->visit(this);
1838 : 6483987 : }
1839 : :
1840 : : void
1841 : 9002941 : traversing_visitor::visit_functioncall (functioncall* e)
1842 : : {
1843 [ + + ]: 13530996 : for (unsigned i=0; i<e->args.size(); i++)
1844 : 4528055 : e->args[i]->visit (this);
1845 : 9002941 : }
1846 : :
1847 : : void
1848 : 3719674 : traversing_visitor::visit_print_format (print_format* e)
1849 : : {
1850 [ + + ]: 10961691 : for (unsigned i=0; i<e->args.size(); i++)
1851 : 7242021 : e->args[i]->visit (this);
1852 [ + + ]: 3719670 : if (e->hist)
1853 : 1450 : e->hist->visit(this);
1854 : 3719670 : }
1855 : :
1856 : : void
1857 : 19675 : traversing_visitor::visit_stat_op (stat_op* e)
1858 : : {
1859 : 19675 : e->stat->visit (this);
1860 : 19674 : }
1861 : :
1862 : : void
1863 : 1807 : traversing_visitor::visit_hist_op (hist_op* e)
1864 : : {
1865 : 1807 : e->stat->visit (this);
1866 : 1807 : }
1867 : :
1868 : :
1869 : : void
1870 : 8365068 : functioncall_traversing_visitor::visit_functioncall (functioncall* e)
1871 : : {
1872 : 8365068 : traversing_visitor::visit_functioncall (e);
1873 : :
1874 : : // prevent infinite recursion
1875 [ + - ][ + + ]: 8365068 : if (traversed.find (e->referent) == traversed.end ())
1876 : : {
1877 : 3882321 : traversed.insert (e->referent);
1878 : : // recurse
1879 : 3882321 : functiondecl* last_current_function = current_function;
1880 : 3882321 : current_function = e->referent;
1881 : 3882321 : e->referent->body->visit (this);
1882 : 3882303 : current_function = last_current_function;
1883 : : }
1884 : 8365050 : }
1885 : :
1886 : :
1887 : : void
1888 : 19232 : varuse_collecting_visitor::visit_try_block (try_block *s)
1889 : : {
1890 [ + - ]: 19232 : if (s->try_block)
1891 : 19232 : s->try_block->visit (this);
1892 [ + + ]: 19232 : if (s->catch_error_var)
1893 : 15 : written.insert (s->catch_error_var->referent);
1894 [ + + ]: 19232 : if (s->catch_block)
1895 : 19196 : s->catch_block->visit (this);
1896 : :
1897 : : // NB: don't functioncall_traversing_visitor::visit_try_block (s);
1898 : : // since that would count s->catch_error_var as a read also.
1899 : 19232 : }
1900 : :
1901 : :
1902 : : void
1903 : 2212332 : varuse_collecting_visitor::visit_embeddedcode (embeddedcode *s)
1904 : : {
1905 [ - + ]: 2212332 : assert (current_function); // only they get embedded code
1906 : :
1907 : : // Don't allow embedded C functions in unprivileged mode unless
1908 : : // they are tagged with /* unprivileged */ or /* myproc-unprivileged */
1909 : : // or we're in a usermode runtime.
1910 [ + + + + : 2212825 : if (! pr_contains (session.privilege, pr_stapdev) &&
+ - + + +
+ ][ + + ]
1911 : 302 : ! pr_contains (session.privilege, pr_stapsys) &&
1912 : 83 : ! session.runtime_usermode_p () &&
1913 : 83 : s->code.find ("/* unprivileged */") == string::npos &&
1914 : 25 : s->code.find ("/* myproc-unprivileged */") == string::npos)
1915 : 7 : throw semantic_error (_F("function may not be used when --privilege=%s is specified",
1916 : : pr_name (session.privilege)),
1917 [ + - ][ + - ]: 7 : current_function->tok);
[ + - ]
1918 : :
1919 : : // Don't allow /* guru */ functions unless -g is active.
1920 [ + + ][ + + ]: 2212325 : if (!session.guru_mode && s->code.find ("/* guru */") != string::npos)
[ + + ]
1921 : 2 : throw semantic_error (_("function may not be used unless -g is specified"),
1922 [ + - ][ + - ]: 2 : current_function->tok);
1923 : :
1924 : : // PR14524: Support old-style THIS->local syntax on per-function basis.
1925 [ + + ]: 2212323 : if (s->code.find ("/* unmangled */") != string::npos)
1926 : 7 : current_function->mangle_oldstyle = true;
1927 : :
1928 : : // We want to elide embedded-C functions when possible. For
1929 : : // example, each $target variable access is expanded to an
1930 : : // embedded-C function call. Yet, for safety reasons, we should
1931 : : // presume that embedded-C functions have intentional side-effects.
1932 : : //
1933 : : // To tell these two types of functions apart, we apply a
1934 : : // Kludge(tm): we look for a magic string within the function body.
1935 : : // $target variables as rvalues will have this; lvalues won't.
1936 : : // Also, explicit side-effect-free tapset functions will have this.
1937 : :
1938 [ + + ]: 2212323 : if (s->code.find ("/* pure */") != string::npos)
1939 : 2212323 : return;
1940 : :
1941 : 176063 : embedded_seen = true;
1942 : : }
1943 : :
1944 : :
1945 : : // About the same case as above.
1946 : : void
1947 : 161141 : varuse_collecting_visitor::visit_embedded_expr (embedded_expr *e)
1948 : : {
1949 : : // Don't allow embedded C expressions in unprivileged mode unless
1950 : : // they are tagged with /* unprivileged */ or /* myproc-unprivileged */
1951 : : // or we're in a usermode runtime.
1952 [ + + + + : 161150 : if (! pr_contains (session.privilege, pr_stapdev) &&
+ - - + #
# ][ - + ]
1953 : 7 : ! pr_contains (session.privilege, pr_stapsys) &&
1954 : 1 : ! session.runtime_usermode_p () &&
1955 : 1 : e->code.find ("/* unprivileged */") == string::npos &&
1956 : 0 : e->code.find ("/* myproc-unprivileged */") == string::npos)
1957 : 0 : throw semantic_error (_F("embedded expression may not be used when --privilege=%s is specified",
1958 : : pr_name (session.privilege)),
1959 [ # # ][ # # ]: 0 : e->tok);
[ # # ]
1960 : :
1961 : : // Don't allow /* guru */ functions unless -g is active.
1962 [ + + ][ - + ]: 161141 : if (!session.guru_mode && e->code.find ("/* guru */") != string::npos)
[ - + ]
1963 : 0 : throw semantic_error (_("embedded expression may not be used unless -g is specified"),
1964 [ # # ][ # # ]: 0 : e->tok);
1965 : :
1966 : : // We want to elide embedded-C functions when possible. For
1967 : : // example, each $target variable access is expanded to an
1968 : : // embedded-C function call. Yet, for safety reasons, we should
1969 : : // presume that embedded-C functions have intentional side-effects.
1970 : : //
1971 : : // To tell these two types of functions apart, we apply a
1972 : : // Kludge(tm): we look for a magic string within the function body.
1973 : : // $target variables as rvalues will have this; lvalues won't.
1974 : : // Also, explicit side-effect-free tapset functions will have this.
1975 : :
1976 [ + + ]: 161141 : if (e->code.find ("/* pure */") != string::npos)
1977 : 161141 : return;
1978 : :
1979 : 146872 : embedded_seen = true;
1980 : : }
1981 : :
1982 : :
1983 : : void
1984 : 13770 : varuse_collecting_visitor::visit_target_symbol (target_symbol *e)
1985 : : {
1986 : : // Still-unresolved target symbol assignments get treated as
1987 : : // generating side-effects like embedded-C, to prevent premature
1988 : : // elision and later error message suppression (PR5516). rvalue use
1989 : : // of unresolved target symbols is OTOH not considered a side-effect.
1990 : :
1991 [ + + ]: 13770 : if (is_active_lvalue (e))
1992 : 18 : embedded_seen = true;
1993 : :
1994 : 13770 : functioncall_traversing_visitor::visit_target_symbol (e);
1995 : 13770 : }
1996 : :
1997 : : void
1998 : 1883 : varuse_collecting_visitor::visit_cast_op (cast_op *e)
1999 : : {
2000 : : // As with target_symbols, unresolved cast assignments need to preserved
2001 : : // for later error handling.
2002 [ - + ]: 1883 : if (is_active_lvalue (e))
2003 : 0 : embedded_seen = true;
2004 : :
2005 : 1883 : functioncall_traversing_visitor::visit_cast_op (e);
2006 : 1883 : }
2007 : :
2008 : : void
2009 : 31 : varuse_collecting_visitor::visit_defined_op (defined_op *e)
2010 : : {
2011 : : // XXX
2012 : 31 : functioncall_traversing_visitor::visit_defined_op (e);
2013 : 31 : }
2014 : :
2015 : : void
2016 : 21 : varuse_collecting_visitor::visit_entry_op (entry_op *e)
2017 : : {
2018 : : // XXX
2019 : 21 : functioncall_traversing_visitor::visit_entry_op (e);
2020 : 21 : }
2021 : :
2022 : :
2023 : : void
2024 : 6 : varuse_collecting_visitor::visit_perf_op (perf_op *e)
2025 : : {
2026 : 6 : functioncall_traversing_visitor::visit_perf_op (e);
2027 : 6 : }
2028 : :
2029 : :
2030 : : void
2031 : 2217059 : varuse_collecting_visitor::visit_print_format (print_format* e)
2032 : : {
2033 : : // NB: Instead of being top-level statements, "print" and "printf"
2034 : : // are implemented as statement-expressions containing a
2035 : : // print_format. They have side-effects, but not via the
2036 : : // embedded-code detection method above.
2037 : : //
2038 : : // But sprint and sprintf don't have side-effects.
2039 : :
2040 : 2217059 : bool last_lvalue_read = current_lvalue_read;
2041 : 2217059 : current_lvalue_read = true;
2042 [ + + ]: 2217059 : if (e->print_to_stream)
2043 : 1340245 : embedded_seen = true; // a proxy for "has unknown side-effects"
2044 : :
2045 : 2217059 : functioncall_traversing_visitor::visit_print_format (e);
2046 : 2217059 : current_lvalue_read = last_lvalue_read;
2047 : 2217059 : }
2048 : :
2049 : :
2050 : : void
2051 : 8374212 : varuse_collecting_visitor::visit_assignment (assignment *e)
2052 : : {
2053 [ + + ][ + + ]: 8374212 : if (e->op == "=" || e->op == "<<<") // pure writes
[ + + ]
2054 : : {
2055 : 8309550 : expression* last_lvalue = current_lvalue;
2056 : 8309550 : bool last_lvalue_read = current_lvalue_read;
2057 : 8309550 : current_lvalue = e->left; // leave a mark for ::visit_symbol
2058 : 8309550 : current_lvalue_read = true;
2059 : 8309550 : functioncall_traversing_visitor::visit_assignment (e);
2060 : 8309548 : current_lvalue = last_lvalue;
2061 : 8309548 : current_lvalue_read = last_lvalue_read;
2062 : : }
2063 : : else // read-modify-writes
2064 : : {
2065 : 64662 : expression* last_lrvalue = current_lrvalue;
2066 : 64662 : current_lrvalue = e->left; // leave a mark for ::visit_symbol
2067 : 64662 : functioncall_traversing_visitor::visit_assignment (e);
2068 : 64662 : current_lrvalue = last_lrvalue;
2069 : : }
2070 : 8374210 : }
2071 : :
2072 : : void
2073 : 17904088 : varuse_collecting_visitor::visit_symbol (symbol *e)
2074 : : {
2075 [ - + ]: 17904088 : if (e->referent == 0)
2076 [ # # ][ # # ]: 0 : throw semantic_error (_("symbol without referent"), e->tok);
2077 : :
2078 : : // We could handle initialized globals by marking them as "written".
2079 : : // However, this current visitor may be called for a function or
2080 : : // probe body, from the point of view of which this global is
2081 : : // already initialized, so not written.
2082 : : /*
2083 : : if (e->referent->init)
2084 : : written.insert (e->referent);
2085 : : */
2086 : :
2087 [ + + ][ + + ]: 17904088 : if (current_lvalue == e || current_lrvalue == e)
2088 : : {
2089 : 9051214 : written.insert (e->referent);
2090 : : }
2091 [ + + ][ - + ]: 17904088 : if (current_lvalue != e || current_lrvalue == e)
2092 : : {
2093 : 9590485 : read.insert (e->referent);
2094 : : }
2095 : :
2096 [ + + ]: 17904088 : if (current_lrvalue == e)
2097 : : {
2098 [ + + ]: 737611 : if (current_lvalue_read)
2099 : 89903 : used.insert (e->referent);
2100 : : }
2101 [ + + ]: 17166477 : else if (current_lvalue != e)
2102 : 8852874 : used.insert (e->referent);
2103 : 17904088 : }
2104 : :
2105 : : // NB: stat_op need not be overridden, since it will get to
2106 : : // visit_symbol and only as a possible rvalue.
2107 : :
2108 : :
2109 : : void
2110 : 5833719 : varuse_collecting_visitor::visit_arrayindex (arrayindex *e)
2111 : : {
2112 : : // Hooking this callback is necessary because of the hacky
2113 : : // statistics representation. For the expression "i[4] = 5", the
2114 : : // incoming lvalue will point to this arrayindex. However, the
2115 : : // symbol corresponding to the "i[4]" is multiply inherited with
2116 : : // arrayindex. If the symbol base part of this object is not at
2117 : : // offset 0, then static_cast<symbol*>(e) may result in a different
2118 : : // address, and not match lvalue by number when we recurse that way.
2119 : : // So we explicitly override the incoming lvalue/lrvalue values to
2120 : : // point at the embedded objects' actual base addresses.
2121 : :
2122 : 5833719 : expression* last_lrvalue = current_lrvalue;
2123 : 5833719 : expression* last_lvalue = current_lvalue;
2124 : :
2125 : 5833719 : symbol *array = NULL;
2126 : 5833719 : hist_op *hist = NULL;
2127 [ + - ]: 5833719 : classify_indexable(e->base, array, hist);
2128 [ + + ]: 5833719 : expression *value = array ?: hist->stat;
2129 : :
2130 [ + + ]: 5833719 : if (current_lrvalue == e) current_lrvalue = value;
2131 [ + + ]: 5833719 : if (current_lvalue == e) current_lvalue = value;
2132 [ + - ]: 5833719 : functioncall_traversing_visitor::visit_arrayindex (e);
2133 : :
2134 : 5833719 : current_lrvalue = last_lrvalue;
2135 : 5833719 : current_lvalue = last_lvalue;
2136 : 5833719 : }
2137 : :
2138 : :
2139 : : void
2140 : 18984 : varuse_collecting_visitor::visit_pre_crement (pre_crement *e)
2141 : : {
2142 : 18984 : expression* last_lrvalue = current_lrvalue;
2143 : 18984 : current_lrvalue = e->operand; // leave a mark for ::visit_symbol
2144 : 18984 : functioncall_traversing_visitor::visit_pre_crement (e);
2145 : 18984 : current_lrvalue = last_lrvalue;
2146 : 18984 : }
2147 : :
2148 : : void
2149 : 623092 : varuse_collecting_visitor::visit_post_crement (post_crement *e)
2150 : : {
2151 : 623092 : expression* last_lrvalue = current_lrvalue;
2152 : 623092 : current_lrvalue = e->operand; // leave a mark for ::visit_symbol
2153 : 623092 : functioncall_traversing_visitor::visit_post_crement (e);
2154 : 623092 : current_lrvalue = last_lrvalue;
2155 : 623092 : }
2156 : :
2157 : : void
2158 : 2325 : varuse_collecting_visitor::visit_foreach_loop (foreach_loop* s)
2159 : : {
2160 : : // NB: we duplicate so don't bother call
2161 : : // functioncall_traversing_visitor::visit_foreach_loop (s);
2162 : :
2163 : 2325 : s->base->visit(this);
2164 : :
2165 : : // If the collection is sorted, imply a "write" access to the
2166 : : // array in addition to the "read" one already noted above.
2167 [ + + ]: 2325 : if (s->sort_direction)
2168 : : {
2169 : 1126 : symbol *array = NULL;
2170 : 1126 : hist_op *hist = NULL;
2171 [ + - ]: 1126 : classify_indexable (s->base, array, hist);
2172 [ + - ][ + - ]: 1126 : if (array) this->written.insert (array->referent);
2173 : : // XXX: Can hist_op iterations be sorted?
2174 : : }
2175 : :
2176 : : // NB: don't forget to visit the index expressions, which are lvalues.
2177 [ + + ]: 6366 : for (unsigned i=0; i<s->indexes.size(); i++)
2178 : : {
2179 : 4041 : expression* last_lvalue = current_lvalue;
2180 : 4041 : current_lvalue = s->indexes[i]; // leave a mark for ::visit_symbol
2181 : 4041 : s->indexes[i]->visit (this);
2182 : 4041 : current_lvalue = last_lvalue;
2183 : : }
2184 : :
2185 : : // The value is an lvalue too
2186 [ + + ]: 2325 : if (s->value)
2187 : : {
2188 : 34 : expression* last_lvalue = current_lvalue;
2189 : 34 : current_lvalue = s->value; // leave a mark for ::visit_symbol
2190 : 34 : s->value->visit (this);
2191 : 34 : current_lvalue = last_lvalue;
2192 : : }
2193 : :
2194 [ + + ]: 2325 : if (s->limit)
2195 : 439 : s->limit->visit (this);
2196 : :
2197 : 2325 : s->block->visit (this);
2198 : 2325 : }
2199 : :
2200 : :
2201 : : void
2202 : 30873 : varuse_collecting_visitor::visit_delete_statement (delete_statement* s)
2203 : : {
2204 : : // Ideally, this would be treated like an assignment: a plain write
2205 : : // to the underlying value ("lvalue"). XXX: However, the
2206 : : // optimization pass is not smart enough to remove an unneeded
2207 : : // "delete" yet, so we pose more like a *crement ("lrvalue"). This
2208 : : // should protect the underlying value from optimizional mischief.
2209 : 30873 : expression* last_lrvalue = current_lrvalue;
2210 : 30873 : bool last_lvalue_read = current_lvalue_read;
2211 : 30873 : current_lrvalue = s->value; // leave a mark for ::visit_symbol
2212 : 30873 : current_lvalue_read = true;
2213 : 30873 : functioncall_traversing_visitor::visit_delete_statement (s);
2214 : 30873 : current_lrvalue = last_lrvalue;
2215 : 30873 : current_lvalue_read = last_lvalue_read;
2216 : 30873 : }
2217 : :
2218 : : bool
2219 : 84925 : varuse_collecting_visitor::side_effect_free ()
2220 : : {
2221 [ + + ][ + + ]: 84925 : return (written.empty() && !embedded_seen);
2222 : : }
2223 : :
2224 : :
2225 : : bool
2226 : 1547897 : varuse_collecting_visitor::side_effect_free_wrt (const set<vardecl*>& vars)
2227 : : {
2228 : : // A looser notion of side-effect-freeness with respect to a given
2229 : : // list of variables.
2230 : :
2231 : : // That's useful because the written list may consist of local
2232 : : // variables of called functions. But visible side-effects only
2233 : : // occur if the client's locals, or any globals are written-to.
2234 : :
2235 [ + - ]: 1547897 : set<vardecl*> intersection;
2236 [ + - ]: 1547897 : insert_iterator<set<vardecl*> > int_it (intersection, intersection.begin());
2237 : : set_intersection (written.begin(), written.end(),
2238 : : vars.begin(), vars.end(),
2239 [ + - ][ + - ]: 1547897 : int_it);
[ + - ][ + - ]
[ + - ]
2240 : :
2241 [ + - ][ + + ]: 1547897 : return (intersection.empty() && !embedded_seen);
[ + + ][ + - ]
2242 : : }
2243 : :
2244 : :
2245 : :
2246 : :
2247 : : // ------------------------------------------------------------------------
2248 : :
2249 : :
2250 [ + - ]: 53800 : throwing_visitor::throwing_visitor (const std::string& m): msg (m) {}
2251 [ + - ]: 863766 : throwing_visitor::throwing_visitor (): msg (_("invalid element")) {}
2252 : :
2253 : :
2254 : : void
2255 : 0 : throwing_visitor::throwone (const token* t)
2256 : : {
2257 [ # # ]: 0 : throw semantic_error (msg, t);
2258 : : }
2259 : :
2260 : : void
2261 : 0 : throwing_visitor::visit_block (block* s)
2262 : : {
2263 : 0 : throwone (s->tok);
2264 : 0 : }
2265 : :
2266 : : void
2267 : 0 : throwing_visitor::visit_try_block (try_block* s)
2268 : : {
2269 : 0 : throwone (s->tok);
2270 : 0 : }
2271 : :
2272 : :
2273 : : void
2274 : 0 : throwing_visitor::visit_embeddedcode (embeddedcode* s)
2275 : : {
2276 : 0 : throwone (s->tok);
2277 : 0 : }
2278 : :
2279 : : void
2280 : 0 : throwing_visitor::visit_null_statement (null_statement* s)
2281 : : {
2282 : 0 : throwone (s->tok);
2283 : 0 : }
2284 : :
2285 : : void
2286 : 0 : throwing_visitor::visit_expr_statement (expr_statement* s)
2287 : : {
2288 : 0 : throwone (s->tok);
2289 : 0 : }
2290 : :
2291 : : void
2292 : 0 : throwing_visitor::visit_if_statement (if_statement* s)
2293 : : {
2294 : 0 : throwone (s->tok);
2295 : 0 : }
2296 : :
2297 : : void
2298 : 0 : throwing_visitor::visit_for_loop (for_loop* s)
2299 : : {
2300 : 0 : throwone (s->tok);
2301 : 0 : }
2302 : :
2303 : : void
2304 : 0 : throwing_visitor::visit_foreach_loop (foreach_loop* s)
2305 : : {
2306 : 0 : throwone (s->tok);
2307 : 0 : }
2308 : :
2309 : : void
2310 : 0 : throwing_visitor::visit_return_statement (return_statement* s)
2311 : : {
2312 : 0 : throwone (s->tok);
2313 : 0 : }
2314 : :
2315 : : void
2316 : 0 : throwing_visitor::visit_delete_statement (delete_statement* s)
2317 : : {
2318 : 0 : throwone (s->tok);
2319 : 0 : }
2320 : :
2321 : : void
2322 : 0 : throwing_visitor::visit_next_statement (next_statement* s)
2323 : : {
2324 : 0 : throwone (s->tok);
2325 : 0 : }
2326 : :
2327 : : void
2328 : 0 : throwing_visitor::visit_break_statement (break_statement* s)
2329 : : {
2330 : 0 : throwone (s->tok);
2331 : 0 : }
2332 : :
2333 : : void
2334 : 0 : throwing_visitor::visit_continue_statement (continue_statement* s)
2335 : : {
2336 : 0 : throwone (s->tok);
2337 : 0 : }
2338 : :
2339 : : void
2340 : 0 : throwing_visitor::visit_literal_string (literal_string* e)
2341 : : {
2342 : 0 : throwone (e->tok);
2343 : 0 : }
2344 : :
2345 : : void
2346 : 1 : throwing_visitor::visit_literal_number (literal_number* e)
2347 : : {
2348 : 1 : throwone (e->tok);
2349 : 0 : }
2350 : :
2351 : : void
2352 : 0 : throwing_visitor::visit_embedded_expr (embedded_expr* e)
2353 : : {
2354 : 0 : throwone (e->tok);
2355 : 0 : }
2356 : :
2357 : : void
2358 : 0 : throwing_visitor::visit_binary_expression (binary_expression* e)
2359 : : {
2360 : 0 : throwone (e->tok);
2361 : 0 : }
2362 : :
2363 : : void
2364 : 0 : throwing_visitor::visit_unary_expression (unary_expression* e)
2365 : : {
2366 : 0 : throwone (e->tok);
2367 : 0 : }
2368 : :
2369 : : void
2370 : 0 : throwing_visitor::visit_pre_crement (pre_crement* e)
2371 : : {
2372 : 0 : throwone (e->tok);
2373 : 0 : }
2374 : :
2375 : : void
2376 : 0 : throwing_visitor::visit_post_crement (post_crement* e)
2377 : : {
2378 : 0 : throwone (e->tok);
2379 : 0 : }
2380 : :
2381 : :
2382 : : void
2383 : 0 : throwing_visitor::visit_logical_or_expr (logical_or_expr* e)
2384 : : {
2385 : 0 : throwone (e->tok);
2386 : 0 : }
2387 : :
2388 : : void
2389 : 0 : throwing_visitor::visit_logical_and_expr (logical_and_expr* e)
2390 : : {
2391 : 0 : throwone (e->tok);
2392 : 0 : }
2393 : :
2394 : : void
2395 : 0 : throwing_visitor::visit_array_in (array_in* e)
2396 : : {
2397 : 0 : throwone (e->tok);
2398 : 0 : }
2399 : :
2400 : : void
2401 : 0 : throwing_visitor::visit_regex_query (regex_query* e)
2402 : : {
2403 : 0 : throwone (e->tok);
2404 : 0 : }
2405 : :
2406 : : void
2407 : 0 : throwing_visitor::visit_comparison (comparison* e)
2408 : : {
2409 : 0 : throwone (e->tok);
2410 : 0 : }
2411 : :
2412 : : void
2413 : 0 : throwing_visitor::visit_concatenation (concatenation* e)
2414 : : {
2415 : 0 : throwone (e->tok);
2416 : 0 : }
2417 : :
2418 : : void
2419 : 0 : throwing_visitor::visit_ternary_expression (ternary_expression* e)
2420 : : {
2421 : 0 : throwone (e->tok);
2422 : 0 : }
2423 : :
2424 : : void
2425 : 0 : throwing_visitor::visit_assignment (assignment* e)
2426 : : {
2427 : 0 : throwone (e->tok);
2428 : 0 : }
2429 : :
2430 : : void
2431 : 0 : throwing_visitor::visit_symbol (symbol* e)
2432 : : {
2433 : 0 : throwone (e->tok);
2434 : 0 : }
2435 : :
2436 : : void
2437 : 0 : throwing_visitor::visit_target_symbol (target_symbol* e)
2438 : : {
2439 : 0 : throwone (e->tok);
2440 : 0 : }
2441 : :
2442 : : void
2443 : 0 : throwing_visitor::visit_cast_op (cast_op* e)
2444 : : {
2445 : 0 : throwone (e->tok);
2446 : 0 : }
2447 : :
2448 : : void
2449 : 0 : throwing_visitor::visit_defined_op (defined_op* e)
2450 : : {
2451 : 0 : throwone (e->tok);
2452 : 0 : }
2453 : :
2454 : : void
2455 : 0 : throwing_visitor::visit_entry_op (entry_op* e)
2456 : : {
2457 : 0 : throwone (e->tok);
2458 : 0 : }
2459 : :
2460 : :
2461 : : void
2462 : 0 : throwing_visitor::visit_perf_op (perf_op* e)
2463 : : {
2464 : 0 : throwone (e->tok);
2465 : 0 : }
2466 : :
2467 : :
2468 : : void
2469 : 0 : throwing_visitor::visit_arrayindex (arrayindex* e)
2470 : : {
2471 : 0 : throwone (e->tok);
2472 : 0 : }
2473 : :
2474 : : void
2475 : 0 : throwing_visitor::visit_functioncall (functioncall* e)
2476 : : {
2477 : 0 : throwone (e->tok);
2478 : 0 : }
2479 : :
2480 : : void
2481 : 0 : throwing_visitor::visit_print_format (print_format* e)
2482 : : {
2483 : 0 : throwone (e->tok);
2484 : 0 : }
2485 : :
2486 : : void
2487 : 0 : throwing_visitor::visit_stat_op (stat_op* e)
2488 : : {
2489 : 0 : throwone (e->tok);
2490 : 0 : }
2491 : :
2492 : : void
2493 : 0 : throwing_visitor::visit_hist_op (hist_op* e)
2494 : : {
2495 : 0 : throwone (e->tok);
2496 : 0 : }
2497 : :
2498 : :
2499 : : // ------------------------------------------------------------------------
2500 : :
2501 : :
2502 : : void
2503 : 3415583 : update_visitor::visit_block (block* s)
2504 : : {
2505 [ + + ]: 10581740 : for (unsigned i = 0; i < s->statements.size(); ++i)
2506 : 7166168 : replace (s->statements[i]);
2507 : 3415572 : provide (s);
2508 : 3415572 : }
2509 : :
2510 : : void
2511 : 14526 : update_visitor::visit_try_block (try_block* s)
2512 : : {
2513 : 14526 : replace (s->try_block);
2514 : 14526 : replace (s->catch_error_var);
2515 : 14526 : replace (s->catch_block);
2516 : 14526 : provide (s);
2517 : 14526 : }
2518 : :
2519 : : void
2520 : 1677786 : update_visitor::visit_embeddedcode (embeddedcode* s)
2521 : : {
2522 : 1677786 : provide (s);
2523 : 1677786 : }
2524 : :
2525 : : void
2526 : 533382 : update_visitor::visit_null_statement (null_statement* s)
2527 : : {
2528 : 533382 : provide (s);
2529 : 533382 : }
2530 : :
2531 : : void
2532 : 4408892 : update_visitor::visit_expr_statement (expr_statement* s)
2533 : : {
2534 : 4408892 : replace (s->value);
2535 : 4408886 : provide (s);
2536 : 4408886 : }
2537 : :
2538 : : void
2539 : 1178975 : update_visitor::visit_if_statement (if_statement* s)
2540 : : {
2541 : 1178975 : replace (s->condition);
2542 : 1178975 : replace (s->thenblock);
2543 : 1178975 : replace (s->elseblock);
2544 : 1178975 : provide (s);
2545 : 1178975 : }
2546 : :
2547 : : void
2548 : 2829 : update_visitor::visit_for_loop (for_loop* s)
2549 : : {
2550 : 2829 : replace (s->init);
2551 : 2829 : replace (s->cond);
2552 : 2829 : replace (s->incr);
2553 : 2829 : replace (s->block);
2554 : 2829 : provide (s);
2555 : 2829 : }
2556 : :
2557 : : void
2558 : 1423 : update_visitor::visit_foreach_loop (foreach_loop* s)
2559 : : {
2560 [ + + ]: 3708 : for (unsigned i = 0; i < s->indexes.size(); ++i)
2561 : 2285 : replace (s->indexes[i]);
2562 : 1423 : replace (s->base);
2563 : 1423 : replace (s->value);
2564 : 1423 : replace (s->limit);
2565 : 1423 : replace (s->block);
2566 : 1423 : provide (s);
2567 : 1423 : }
2568 : :
2569 : : void
2570 : 546042 : update_visitor::visit_return_statement (return_statement* s)
2571 : : {
2572 : 546042 : replace (s->value);
2573 : 546042 : provide (s);
2574 : 546042 : }
2575 : :
2576 : : void
2577 : 36768 : update_visitor::visit_delete_statement (delete_statement* s)
2578 : : {
2579 : 36768 : replace (s->value);
2580 : 36768 : provide (s);
2581 : 36768 : }
2582 : :
2583 : : void
2584 : 84757 : update_visitor::visit_next_statement (next_statement* s)
2585 : : {
2586 : 84757 : provide (s);
2587 : 84757 : }
2588 : :
2589 : : void
2590 : 3492 : update_visitor::visit_break_statement (break_statement* s)
2591 : : {
2592 : 3492 : provide (s);
2593 : 3492 : }
2594 : :
2595 : : void
2596 : 563 : update_visitor::visit_continue_statement (continue_statement* s)
2597 : : {
2598 : 563 : provide (s);
2599 : 563 : }
2600 : :
2601 : : void
2602 : 785461 : update_visitor::visit_literal_string (literal_string* e)
2603 : : {
2604 : 785461 : provide (e);
2605 : 785461 : }
2606 : :
2607 : : void
2608 : 1249211 : update_visitor::visit_literal_number (literal_number* e)
2609 : : {
2610 : 1249211 : provide (e);
2611 : 1249211 : }
2612 : :
2613 : : void
2614 : 83792 : update_visitor::visit_embedded_expr (embedded_expr* e)
2615 : : {
2616 : 83792 : provide (e);
2617 : 83792 : }
2618 : :
2619 : : void
2620 : 76229 : update_visitor::visit_binary_expression (binary_expression* e)
2621 : : {
2622 : 76229 : replace (e->left);
2623 : 76229 : replace (e->right);
2624 : 76229 : provide (e);
2625 : 76229 : }
2626 : :
2627 : : void
2628 : 24737 : update_visitor::visit_unary_expression (unary_expression* e)
2629 : : {
2630 : 24737 : replace (e->operand);
2631 : 24737 : provide (e);
2632 : 24737 : }
2633 : :
2634 : : void
2635 : 13486 : update_visitor::visit_pre_crement (pre_crement* e)
2636 : : {
2637 : 13486 : replace (e->operand);
2638 : 13486 : provide (e);
2639 : 13486 : }
2640 : :
2641 : : void
2642 : 478491 : update_visitor::visit_post_crement (post_crement* e)
2643 : : {
2644 : 478491 : replace (e->operand);
2645 : 478491 : provide (e);
2646 : 478491 : }
2647 : :
2648 : :
2649 : : void
2650 : 9190 : update_visitor::visit_logical_or_expr (logical_or_expr* e)
2651 : : {
2652 : 9190 : replace (e->left);
2653 : 9190 : replace (e->right);
2654 : 9190 : provide (e);
2655 : 9190 : }
2656 : :
2657 : : void
2658 : 19427 : update_visitor::visit_logical_and_expr (logical_and_expr* e)
2659 : : {
2660 : 19427 : replace (e->left);
2661 : 19427 : replace (e->right);
2662 : 19427 : provide (e);
2663 : 19427 : }
2664 : :
2665 : : void
2666 : 10602 : update_visitor::visit_array_in (array_in* e)
2667 : : {
2668 : 10602 : replace (e->operand);
2669 : 10602 : provide (e);
2670 : 10602 : }
2671 : :
2672 : : void
2673 : 284 : update_visitor::visit_regex_query (regex_query* e)
2674 : : {
2675 : 284 : replace (e->left);
2676 : 284 : replace (e->right); // TODOXXX do we need to replace literal in RHS?
2677 : 284 : provide (e);
2678 : 284 : }
2679 : :
2680 : : void
2681 : 624647 : update_visitor::visit_comparison (comparison* e)
2682 : : {
2683 : 624647 : replace (e->left);
2684 : 624647 : replace (e->right);
2685 : 624647 : provide (e);
2686 : 624647 : }
2687 : :
2688 : : void
2689 : 53640 : update_visitor::visit_concatenation (concatenation* e)
2690 : : {
2691 : 53640 : replace (e->left);
2692 : 53640 : replace (e->right);
2693 : 53640 : provide (e);
2694 : 53640 : }
2695 : :
2696 : : void
2697 : 26552 : update_visitor::visit_ternary_expression (ternary_expression* e)
2698 : : {
2699 : 26552 : replace (e->cond);
2700 : 26552 : replace (e->truevalue);
2701 : 26552 : replace (e->falsevalue);
2702 : 26552 : provide (e);
2703 : 26552 : }
2704 : :
2705 : : void
2706 : 1085314 : update_visitor::visit_assignment (assignment* e)
2707 : : {
2708 : 1085314 : replace (e->left);
2709 : 1085314 : replace (e->right);
2710 : 1085314 : provide (e);
2711 : 1085314 : }
2712 : :
2713 : : void
2714 : 7624348 : update_visitor::visit_symbol (symbol* e)
2715 : : {
2716 : 7624348 : provide (e);
2717 : 7624348 : }
2718 : :
2719 : : void
2720 : 135637 : update_visitor::visit_target_symbol (target_symbol* e)
2721 : : {
2722 : 135637 : e->visit_components (this);
2723 : 135637 : provide (e);
2724 : 135637 : }
2725 : :
2726 : : void
2727 : 1394 : update_visitor::visit_cast_op (cast_op* e)
2728 : : {
2729 : 1394 : replace (e->operand);
2730 : 1394 : e->visit_components (this);
2731 : 1394 : provide (e);
2732 : 1394 : }
2733 : :
2734 : : void
2735 : 5389 : update_visitor::visit_defined_op (defined_op* e)
2736 : : {
2737 : 5389 : replace (e->operand);
2738 : 5389 : provide (e);
2739 : 5389 : }
2740 : :
2741 : : void
2742 : 1127 : update_visitor::visit_entry_op (entry_op* e)
2743 : : {
2744 : 1127 : replace (e->operand);
2745 : 1127 : provide (e);
2746 : 1127 : }
2747 : :
2748 : : void
2749 : 12 : update_visitor::visit_perf_op (perf_op* e)
2750 : : {
2751 : 12 : replace (e->operand);
2752 : 12 : provide (e);
2753 : 12 : }
2754 : :
2755 : : void
2756 : 856691 : update_visitor::visit_arrayindex (arrayindex* e)
2757 : : {
2758 : 856691 : replace (e->base);
2759 [ + + ]: 1844486 : for (unsigned i = 0; i < e->indexes.size(); ++i)
2760 : 987795 : replace (e->indexes[i]);
2761 : 856691 : provide (e);
2762 : 856691 : }
2763 : :
2764 : : void
2765 : 3828604 : update_visitor::visit_functioncall (functioncall* e)
2766 : : {
2767 [ + + ]: 5328237 : for (unsigned i = 0; i < e->args.size(); ++i)
2768 : 1499633 : replace (e->args[i]);
2769 : 3828604 : provide (e);
2770 : 3828604 : }
2771 : :
2772 : : void
2773 : 1651014 : update_visitor::visit_print_format (print_format* e)
2774 : : {
2775 [ + + ]: 4954987 : for (unsigned i = 0; i < e->args.size(); ++i)
2776 : 3303974 : replace (e->args[i]);
2777 : 1651013 : replace (e->hist);
2778 : 1651013 : provide (e);
2779 : 1651013 : }
2780 : :
2781 : : void
2782 : 4144 : update_visitor::visit_stat_op (stat_op* e)
2783 : : {
2784 : 4144 : replace (e->stat);
2785 : 4144 : provide (e);
2786 : 4144 : }
2787 : :
2788 : : void
2789 : 826 : update_visitor::visit_hist_op (hist_op* e)
2790 : : {
2791 : 826 : replace (e->stat);
2792 : 826 : provide (e);
2793 : 826 : }
2794 : :
2795 : :
2796 : : // ------------------------------------------------------------------------
2797 : :
2798 : :
2799 : : void
2800 : 628365 : deep_copy_visitor::visit_block (block* s)
2801 : : {
2802 [ + - ]: 628365 : update_visitor::visit_block(new block(*s));
2803 : 628365 : }
2804 : :
2805 : : void
2806 : 53 : deep_copy_visitor::visit_try_block (try_block* s)
2807 : : {
2808 : 53 : update_visitor::visit_try_block(new try_block(*s));
2809 : 53 : }
2810 : :
2811 : : void
2812 : 0 : deep_copy_visitor::visit_embeddedcode (embeddedcode* s)
2813 : : {
2814 [ # # ]: 0 : update_visitor::visit_embeddedcode(new embeddedcode(*s));
2815 : 0 : }
2816 : :
2817 : : void
2818 : 97 : deep_copy_visitor::visit_null_statement (null_statement* s)
2819 : : {
2820 : 97 : update_visitor::visit_null_statement(new null_statement(*s));
2821 : 97 : }
2822 : :
2823 : : void
2824 : 629699 : deep_copy_visitor::visit_expr_statement (expr_statement* s)
2825 : : {
2826 : 629699 : update_visitor::visit_expr_statement(new expr_statement(*s));
2827 : 629699 : }
2828 : :
2829 : : void
2830 : 232462 : deep_copy_visitor::visit_if_statement (if_statement* s)
2831 : : {
2832 : 232462 : update_visitor::visit_if_statement(new if_statement(*s));
2833 : 232462 : }
2834 : :
2835 : : void
2836 : 329 : deep_copy_visitor::visit_for_loop (for_loop* s)
2837 : : {
2838 : 329 : update_visitor::visit_for_loop(new for_loop(*s));
2839 : 329 : }
2840 : :
2841 : : void
2842 : 347 : deep_copy_visitor::visit_foreach_loop (foreach_loop* s)
2843 : : {
2844 [ + - ]: 347 : update_visitor::visit_foreach_loop(new foreach_loop(*s));
2845 : 347 : }
2846 : :
2847 : : void
2848 : 0 : deep_copy_visitor::visit_return_statement (return_statement* s)
2849 : : {
2850 : 0 : update_visitor::visit_return_statement(new return_statement(*s));
2851 : 0 : }
2852 : :
2853 : : void
2854 : 2238 : deep_copy_visitor::visit_delete_statement (delete_statement* s)
2855 : : {
2856 : 2238 : update_visitor::visit_delete_statement(new delete_statement(*s));
2857 : 2238 : }
2858 : :
2859 : : void
2860 : 7286 : deep_copy_visitor::visit_next_statement (next_statement* s)
2861 : : {
2862 : 7286 : update_visitor::visit_next_statement(new next_statement(*s));
2863 : 7286 : }
2864 : :
2865 : : void
2866 : 17 : deep_copy_visitor::visit_break_statement (break_statement* s)
2867 : : {
2868 : 17 : update_visitor::visit_break_statement(new break_statement(*s));
2869 : 17 : }
2870 : :
2871 : : void
2872 : 17 : deep_copy_visitor::visit_continue_statement (continue_statement* s)
2873 : : {
2874 : 17 : update_visitor::visit_continue_statement(new continue_statement(*s));
2875 : 17 : }
2876 : :
2877 : : void
2878 : 84502 : deep_copy_visitor::visit_literal_string (literal_string* e)
2879 : : {
2880 [ + - ]: 84502 : update_visitor::visit_literal_string(new literal_string(*e));
2881 : 84502 : }
2882 : :
2883 : : void
2884 : 195024 : deep_copy_visitor::visit_literal_number (literal_number* e)
2885 : : {
2886 : 195024 : update_visitor::visit_literal_number(new literal_number(*e));
2887 : 195024 : }
2888 : :
2889 : : void
2890 : 621 : deep_copy_visitor::visit_embedded_expr (embedded_expr* e)
2891 : : {
2892 [ + - ]: 621 : update_visitor::visit_embedded_expr(new embedded_expr(*e));
2893 : 621 : }
2894 : :
2895 : : void
2896 : 2852 : deep_copy_visitor::visit_binary_expression (binary_expression* e)
2897 : : {
2898 [ + - ]: 2852 : update_visitor::visit_binary_expression(new binary_expression(*e));
2899 : 2852 : }
2900 : :
2901 : : void
2902 : 3607 : deep_copy_visitor::visit_unary_expression (unary_expression* e)
2903 : : {
2904 [ + - ]: 3607 : update_visitor::visit_unary_expression(new unary_expression(*e));
2905 : 3607 : }
2906 : :
2907 : : void
2908 : 2142 : deep_copy_visitor::visit_pre_crement (pre_crement* e)
2909 : : {
2910 [ + - ]: 2142 : update_visitor::visit_pre_crement(new pre_crement(*e));
2911 : 2142 : }
2912 : :
2913 : : void
2914 : 89563 : deep_copy_visitor::visit_post_crement (post_crement* e)
2915 : : {
2916 [ + - ]: 89563 : update_visitor::visit_post_crement(new post_crement(*e));
2917 : 89563 : }
2918 : :
2919 : :
2920 : : void
2921 : 1630 : deep_copy_visitor::visit_logical_or_expr (logical_or_expr* e)
2922 : : {
2923 [ + - ]: 1630 : update_visitor::visit_logical_or_expr(new logical_or_expr(*e));
2924 : 1630 : }
2925 : :
2926 : : void
2927 : 4518 : deep_copy_visitor::visit_logical_and_expr (logical_and_expr* e)
2928 : : {
2929 [ + - ]: 4518 : update_visitor::visit_logical_and_expr(new logical_and_expr(*e));
2930 : 4518 : }
2931 : :
2932 : : void
2933 : 2761 : deep_copy_visitor::visit_array_in (array_in* e)
2934 : : {
2935 : 2761 : update_visitor::visit_array_in(new array_in(*e));
2936 : 2761 : }
2937 : :
2938 : : void
2939 : 48 : deep_copy_visitor::visit_regex_query (regex_query* e)
2940 : : {
2941 [ + - ]: 48 : update_visitor::visit_regex_query(new regex_query(*e));
2942 : 48 : }
2943 : :
2944 : : void
2945 : 102783 : deep_copy_visitor::visit_comparison (comparison* e)
2946 : : {
2947 [ + - ]: 102783 : update_visitor::visit_comparison(new comparison(*e));
2948 : 102783 : }
2949 : :
2950 : : void
2951 : 1919 : deep_copy_visitor::visit_concatenation (concatenation* e)
2952 : : {
2953 [ + - ]: 1919 : update_visitor::visit_concatenation(new concatenation(*e));
2954 : 1919 : }
2955 : :
2956 : : void
2957 : 5846 : deep_copy_visitor::visit_ternary_expression (ternary_expression* e)
2958 : : {
2959 : 5846 : update_visitor::visit_ternary_expression(new ternary_expression(*e));
2960 : 5846 : }
2961 : :
2962 : : void
2963 : 308744 : deep_copy_visitor::visit_assignment (assignment* e)
2964 : : {
2965 [ + - ]: 308744 : update_visitor::visit_assignment(new assignment(*e));
2966 : 308744 : }
2967 : :
2968 : : void
2969 : 980647 : deep_copy_visitor::visit_symbol (symbol* e)
2970 : : {
2971 [ + - ]: 980647 : symbol* n = new symbol(*e);
2972 : 980647 : n->referent = NULL; // don't copy!
2973 : 980647 : update_visitor::visit_symbol(n);
2974 : 980647 : }
2975 : :
2976 : : void
2977 : 126217 : deep_copy_visitor::visit_target_symbol (target_symbol* e)
2978 : : {
2979 [ + - ]: 126217 : target_symbol* n = new target_symbol(*e);
2980 : 126217 : n->referent = NULL; // don't copy!
2981 : 126217 : update_visitor::visit_target_symbol(n);
2982 : 126217 : }
2983 : :
2984 : : void
2985 : 550 : deep_copy_visitor::visit_cast_op (cast_op* e)
2986 : : {
2987 [ + - ]: 550 : update_visitor::visit_cast_op(new cast_op(*e));
2988 : 550 : }
2989 : :
2990 : : void
2991 : 5377 : deep_copy_visitor::visit_defined_op (defined_op* e)
2992 : : {
2993 : 5377 : update_visitor::visit_defined_op(new defined_op(*e));
2994 : 5377 : }
2995 : :
2996 : : void
2997 : 1110 : deep_copy_visitor::visit_entry_op (entry_op* e)
2998 : : {
2999 : 1110 : update_visitor::visit_entry_op(new entry_op(*e));
3000 : 1110 : }
3001 : :
3002 : : void
3003 : 6 : deep_copy_visitor::visit_perf_op (perf_op* e)
3004 : : {
3005 : 6 : update_visitor::visit_perf_op(new perf_op(*e));
3006 : 6 : }
3007 : :
3008 : : void
3009 : 126049 : deep_copy_visitor::visit_arrayindex (arrayindex* e)
3010 : : {
3011 [ + - ]: 126049 : update_visitor::visit_arrayindex(new arrayindex(*e));
3012 : 126049 : }
3013 : :
3014 : : void
3015 : 373799 : deep_copy_visitor::visit_functioncall (functioncall* e)
3016 : : {
3017 [ + - ]: 373799 : functioncall* n = new functioncall(*e);
3018 : 373799 : n->referent = NULL; // don't copy!
3019 : 373799 : update_visitor::visit_functioncall(n);
3020 : 373799 : }
3021 : :
3022 : : void
3023 : 230210 : deep_copy_visitor::visit_print_format (print_format* e)
3024 : : {
3025 [ + - ]: 230210 : update_visitor::visit_print_format(new print_format(*e));
3026 : 230210 : }
3027 : :
3028 : : void
3029 : 739 : deep_copy_visitor::visit_stat_op (stat_op* e)
3030 : : {
3031 : 739 : update_visitor::visit_stat_op(new stat_op(*e));
3032 : 739 : }
3033 : :
3034 : : void
3035 : 135 : deep_copy_visitor::visit_hist_op (hist_op* e)
3036 : : {
3037 [ + - ]: 135 : update_visitor::visit_hist_op(new hist_op(*e));
3038 [ + - ][ + - ]: 7377 : }
3039 : :
3040 : : /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
|