1 // elaboration functions
2 // Copyright (C) 2005-2019 Red Hat Inc.
3 // Copyright (C) 2008 Intel Corporation
5 // This file is part of systemtap, and is free software. You can
6 // redistribute it and/or modify it under the terms of the GNU General
7 // Public License (GPL); either version 2, or (at your option) any
11 #include "elaborate.h"
12 #include "translate.h"
17 #include "task_finder.h"
18 #include "stapregex.h"
19 #include "stringtable.h"
22 #include <sys/utsname.h>
24 #define __STDC_FORMAT_MACROS
42 // ------------------------------------------------------------------------
44 // Used in probe_point condition construction. Either argument may be
45 // NULL; if both, return NULL too. Resulting expression is a deep
46 // copy for symbol resolution purposes.
47 expression
* add_condition (expression
* a
, expression
* b
)
49 if (!a
&& !b
) return 0;
50 if (! a
) return deep_copy_visitor::deep_copy(b
);
51 if (! b
) return deep_copy_visitor::deep_copy(a
);
56 la
.tok
= a
->tok
; // or could be b->tok
57 return deep_copy_visitor::deep_copy(& la
);
60 // ------------------------------------------------------------------------
64 derived_probe::derived_probe (probe
*p
, probe_point
*l
, bool rewrite_loc
):
65 base (p
), base_pp(l
), group(NULL
), sdt_semaphore_addr(0),
66 session_index((unsigned)-1)
70 this->privileged
= p
->privileged
;
71 this->synthetic
= p
->synthetic
;
72 this->body
= deep_copy_visitor::deep_copy(p
->body
);
75 // make a copy for subclasses which want to rewrite the location
77 l
= new probe_point(*l
);
78 this->locations
.push_back (l
);
83 derived_probe::printsig (ostream
& o
, bool nest
) const
92 derived_probe::printsig_nested (ostream
& o
) const
94 // We'd like to enclose the probe derivation chain in a /* */
95 // comment delimiter. But just printing /* base->printsig() */ is
96 // not enough, since base might itself be a derived_probe. So we,
97 // er, "cleverly" encode our nesting state as a formatting flag for
99 ios::fmtflags f
= o
.flags (ios::internal
);
100 if (f
& ios::internal
)
119 derived_probe::collect_derivation_chain (std::vector
<probe
*> &probes_list
) const
121 probes_list
.push_back(const_cast<derived_probe
*>(this));
122 base
->collect_derivation_chain(probes_list
);
127 derived_probe::collect_derivation_pp_chain (std::vector
<probe_point
*> &pp_list
) const
129 pp_list
.push_back(const_cast<probe_point
*>(this->sole_location()));
130 base
->collect_derivation_pp_chain(pp_list
);
135 derived_probe::derived_locations (bool firstFrom
)
138 vector
<probe_point
*> reference_point
;
139 collect_derivation_pp_chain(reference_point
);
140 if (reference_point
.size() > 0)
141 for(unsigned i
=1; i
<reference_point
.size(); ++i
)
143 if (firstFrom
|| i
>1)
145 o
<< reference_point
[i
]->str(false); // no ?,!,etc
152 derived_probe::sole_location () const
154 if (locations
.size() == 0 || locations
.size() > 1)
155 throw SEMANTIC_ERROR (_N("derived_probe with no locations",
156 "derived_probe with too many locations",
157 locations
.size()), this->tok
);
164 derived_probe::script_location () const
166 // This feeds function::pn() in the tapset, which is documented as the
167 // script-level probe point expression, *after wildcard expansion*.
168 vector
<probe_point
*> chain
;
169 collect_derivation_pp_chain (chain
);
171 // Go backwards until we hit the first well-formed probe point
172 for (int i
=chain
.size()-1; i
>=0; i
--)
173 if (chain
[i
]->well_formed
)
176 // If that didn't work, just fallback to -something-.
177 return sole_location();
182 derived_probe::emit_privilege_assertion (translator_output
* o
)
184 // Emit code which will cause compilation to fail if it is compiled in
185 // unprivileged mode.
186 o
->newline() << "#if ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPDEV) && \\";
187 o
->newline() << " ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPSYS)";
188 o
->newline() << "#error Internal Error: Probe ";
189 probe::printsig (o
->line());
190 o
->line() << " generated in --unprivileged mode";
191 o
->newline() << "#endif";
196 derived_probe::emit_process_owner_assertion (translator_output
* o
)
198 // Emit code which will abort should the current target not belong to the
199 // user in unprivileged mode.
200 o
->newline() << "#if ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPDEV) && \\";
201 o
->newline() << " ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPSYS)";
202 o
->newline(1) << "if (! is_myproc ()) {";
203 o
->newline(1) << "snprintf(c->error_buffer, sizeof(c->error_buffer),";
204 o
->newline() << " \"Internal Error: Process %d does not belong to user %d in probe %s in --unprivileged mode\",";
205 o
->newline() << " current->tgid, _stp_uid, c->probe_point);";
206 o
->newline() << "c->last_error = c->error_buffer;";
207 // NB: since this check occurs before probe locking, its exit should
208 // not be a "goto out", which would attempt unlocking.
209 o
->newline() << "return;";
210 o
->newline(-1) << "}";
211 o
->newline(-1) << "#endif";
215 derived_probe::print_dupe_stamp_unprivileged(ostream
& o
)
217 o
<< _("unprivileged users: authorized") << endl
;
221 derived_probe::print_dupe_stamp_unprivileged_process_owner(ostream
& o
)
223 o
<< _("unprivileged users: authorized for process owner") << endl
;
226 // ------------------------------------------------------------------------
227 // Members of derived_probe_builder
230 derived_probe_builder::build_with_suffix(systemtap_session
&,
233 literal_map_t
const &,
234 std::vector
<derived_probe
*> &,
235 std::vector
<probe_point::component
*>
237 // XXX perhaps build the probe if suffix is empty?
238 // if (suffix.empty()) {
239 // build (sess, use, location, parameters, finished_results);
242 throw SEMANTIC_ERROR (_("invalid suffix for probe"));
246 derived_probe_builder::get_param (literal_map_t
const & params
,
248 interned_string
& value
)
250 literal_map_t::const_iterator i
= params
.find (key
);
251 if (i
== params
.end())
253 literal_string
* ls
= dynamic_cast<literal_string
*>(i
->second
);
262 derived_probe_builder::get_param (literal_map_t
const & params
,
266 literal_map_t::const_iterator i
= params
.find (key
);
267 if (i
== params
.end())
269 if (i
->second
== NULL
)
271 literal_number
* ln
= dynamic_cast<literal_number
*>(i
->second
);
280 derived_probe_builder::has_null_param (literal_map_t
const & params
,
283 literal_map_t::const_iterator i
= params
.find(key
);
284 return (i
!= params
.end() && i
->second
== NULL
);
288 derived_probe_builder::has_param (literal_map_t
const & params
,
291 return (params
.find(key
) != params
.end());
294 // ------------------------------------------------------------------------
295 // Members of match_key.
297 match_key::match_key(interned_string n
)
299 have_parameter(false),
300 parameter_type(pe_unknown
)
304 match_key::match_key(probe_point::component
const & c
)
306 have_parameter(c
.arg
!= NULL
),
307 parameter_type(c
.arg
? c
.arg
->type
: pe_unknown
)
312 match_key::with_number()
314 have_parameter
= true;
315 parameter_type
= pe_long
;
320 match_key::with_string()
322 have_parameter
= true;
323 parameter_type
= pe_string
;
328 match_key::str() const
332 switch (parameter_type
)
334 case pe_string
: return n
+ "(string)";
335 case pe_long
: return n
+ "(number)";
336 default: return n
+ "(...)";
342 match_key::operator<(match_key
const & other
) const
344 return ((name
< other
.name
)
346 || (name
== other
.name
347 && have_parameter
< other
.have_parameter
)
349 || (name
== other
.name
350 && have_parameter
== other
.have_parameter
351 && parameter_type
< other
.parameter_type
));
355 // NB: these are only used in the probe point name components, where
356 // only "*" is permitted.
358 // Within module("bar"), function("foo"), process("baz") strings, real
359 // wildcards are permitted too. See also util.h:contains_glob_chars
362 isglob(interned_string str
)
364 return(str
.find('*') != str
.npos
);
368 isdoubleglob(interned_string str
)
370 return(str
.find("**") != str
.npos
);
374 match_key::globmatch(match_key
const & other
) const
376 const string
& name_str
= name
;
377 const string
& other_str
= other
.name
;
379 return ((fnmatch(name_str
.c_str(), other_str
.c_str(), FNM_NOESCAPE
) == 0)
380 && have_parameter
== other
.have_parameter
381 && parameter_type
== other
.parameter_type
);
384 // ------------------------------------------------------------------------
385 // Members of match_node
386 // ------------------------------------------------------------------------
388 match_node::match_node() :
389 privilege(privilege_t (pr_stapdev
| pr_stapsys
))
394 match_node::bind(match_key
const & k
)
397 throw SEMANTIC_ERROR(_("invalid use of wildcard probe point component"));
399 map
<match_key
, match_node
*>::const_iterator i
= sub
.find(k
);
402 match_node
* n
= new match_node();
403 sub
.insert(make_pair(k
, n
));
408 match_node::bind(derived_probe_builder
* e
)
414 match_node::bind(interned_string k
)
416 return bind(match_key(k
));
420 match_node::bind_str(string
const & k
)
422 return bind(match_key(k
).with_string());
426 match_node::bind_num(string
const & k
)
428 return bind(match_key(k
).with_number());
432 match_node::bind_privilege(privilege_t p
)
439 match_node::find_and_build (systemtap_session
& s
,
440 probe
* p
, probe_point
*loc
, unsigned pos
,
441 vector
<derived_probe
*>& results
,
442 set
<string
>& builders
)
444 save_and_restore
<unsigned> costly(& s
.suppress_costly_diagnostics
,
445 s
.suppress_costly_diagnostics
+ (loc
->optional
|| loc
->sufficient
? 1 : 0));
447 assert (pos
<= loc
->components
.size());
448 if (pos
== loc
->components
.size()) // matched all probe point components so far
453 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
454 alternatives
+= string(" ") + i
->first
.str();
456 throw SEMANTIC_ERROR (_F("probe point truncated (follow: %s)",
457 alternatives
.c_str()),
458 loc
->components
.back()->tok
);
461 if (! pr_contains (privilege
, s
.privilege
))
463 throw SEMANTIC_ERROR (_F("probe point is not allowed for --privilege=%s",
464 pr_name (s
.privilege
)),
465 loc
->components
.back()->tok
);
468 literal_map_t param_map
;
469 for (unsigned i
=0; i
<pos
; i
++)
470 param_map
[loc
->components
[i
]->functor
] = loc
->components
[i
]->arg
;
473 unsigned int num_results
= results
.size();
475 // Iterate over all bound builders
476 for (unsigned k
=0; k
<ends
.size(); k
++)
478 derived_probe_builder
*b
= ends
[k
];
479 b
->build (s
, p
, loc
, param_map
, results
);
482 // Collect names of builders attempted for error reporting
483 if (results
.size() == num_results
)
485 for (unsigned k
=0; k
<ends
.size(); k
++)
486 builders
.insert(ends
[k
]->name());
489 else if (isdoubleglob(loc
->components
[pos
]->functor
)) // ** wildcard?
491 unsigned int num_results
= results
.size();
493 // When faced with "foo**bar", we try "foo*bar" and "foo*.**bar"
495 const probe_point::component
*comp
= loc
->components
[pos
];
496 string functor
= comp
->functor
;
497 size_t glob_start
= functor
.find("**");
498 size_t glob_end
= functor
.find_first_not_of('*', glob_start
);
499 string prefix
= functor
.substr(0, glob_start
);
500 string suffix
= ((glob_end
!= string::npos
) ?
501 functor
.substr(glob_end
) : "");
503 // Synthesize "foo*bar"
504 probe_point
*simple_pp
= new probe_point(*loc
);
505 probe_point::component
*simple_comp
= new probe_point::component(*comp
);
506 simple_comp
->functor
= prefix
+ "*" + suffix
;
507 simple_comp
->from_glob
= true;
508 simple_pp
->components
[pos
] = simple_comp
;
511 find_and_build (s
, p
, simple_pp
, pos
, results
, builders
);
513 catch (const semantic_error
& e
)
515 // Ignore semantic_errors.
518 // Cleanup if we didn't find anything
519 if (results
.size() == num_results
)
525 num_results
= results
.size();
527 // Synthesize "foo*.**bar"
528 // NB: any component arg should attach to the latter part only
529 probe_point
*expanded_pp
= new probe_point(*loc
);
530 probe_point::component
*expanded_comp_pre
= new probe_point::component(*comp
);
531 expanded_comp_pre
->functor
= prefix
+ "*";
532 expanded_comp_pre
->from_glob
= true;
533 expanded_comp_pre
->arg
= NULL
;
534 probe_point::component
*expanded_comp_post
= new probe_point::component(*comp
);
535 expanded_comp_post
->functor
= string("**") + suffix
;
536 expanded_pp
->components
[pos
] = expanded_comp_pre
;
537 expanded_pp
->components
.insert(expanded_pp
->components
.begin() + pos
+ 1,
541 find_and_build (s
, p
, expanded_pp
, pos
, results
, builders
);
543 catch (const semantic_error
& e
)
545 // Ignore semantic_errors.
548 // Cleanup if we didn't find anything
549 if (results
.size() == num_results
)
552 delete expanded_comp_pre
;
553 delete expanded_comp_post
;
556 // Try suffix expansion only if no matches found:
557 if (num_results
== results
.size())
558 this->try_suffix_expansion (s
, p
, loc
, pos
, results
);
560 if (! loc
->optional
&& num_results
== results
.size())
562 // We didn't find any wildcard matches (since the size of
563 // the result vector didn't change). Throw an error.
564 string sugs
= suggest_functors(s
, functor
);
565 throw SEMANTIC_ERROR (_F("probe point mismatch: didn't find any wildcard matches%s",
566 sugs
.empty() ? "" : (" (similar: " + sugs
+ ")").c_str()),
570 else if (isglob(loc
->components
[pos
]->functor
)) // wildcard?
572 match_key
match (* loc
->components
[pos
]);
574 // Call find_and_build for each possible match. Ignore errors -
575 // unless we don't find any match.
576 unsigned int num_results
= results
.size();
577 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
579 const match_key
& subkey
= i
->first
;
580 match_node
* subnode
= i
->second
;
582 assert_no_interrupts();
584 if (match
.globmatch(subkey
))
587 clog
<< _F("wildcard '%s' matched '%s'",
588 loc
->components
[pos
]->functor
.to_string().c_str(),
589 subkey
.name
.to_string().c_str()) << endl
;
591 // When we have a wildcard, we need to create a copy of
592 // the probe point. Then we'll create a copy of the
593 // wildcard component, and substitute the non-wildcard
595 probe_point
*non_wildcard_pp
= new probe_point(*loc
);
596 probe_point::component
*non_wildcard_component
597 = new probe_point::component(*loc
->components
[pos
]);
598 non_wildcard_component
->functor
= subkey
.name
;
599 non_wildcard_component
->from_glob
= true;
600 non_wildcard_pp
->components
[pos
] = non_wildcard_component
;
602 // NB: probe conditions are not attached at the wildcard
603 // (component/functor) level, but at the overall
604 // probe_point level.
606 unsigned int inner_results
= results
.size();
608 // recurse (with the non-wildcard probe point)
611 subnode
->find_and_build (s
, p
, non_wildcard_pp
, pos
+1,
614 catch (const semantic_error
& e
)
616 // Ignore semantic_errors while expanding wildcards.
617 // If we get done and nothing was expanded, the code
618 // following the loop will complain.
621 if (results
.size() == inner_results
)
623 // If this wildcard didn't match, cleanup.
624 delete non_wildcard_pp
;
625 delete non_wildcard_component
;
630 // Try suffix expansion only if no matches found:
631 if (num_results
== results
.size())
632 this->try_suffix_expansion (s
, p
, loc
, pos
, results
);
634 if (! loc
->optional
&& num_results
== results
.size())
636 // We didn't find any wildcard matches (since the size of
637 // the result vector didn't change). Throw an error.
638 string sugs
= suggest_functors(s
, loc
->components
[pos
]->functor
);
639 throw SEMANTIC_ERROR (_F("probe point mismatch: didn't find any wildcard matches%s",
640 sugs
.empty() ? "" : (" (similar: " + sugs
+ ")").c_str()),
641 loc
->components
[pos
]->tok
);
646 match_key
match (* loc
->components
[pos
]);
647 sub_map_iterator_t i
= sub
.find (match
);
649 if (i
!= sub
.end()) // match found
651 match_node
* subnode
= i
->second
;
653 subnode
->find_and_build (s
, p
, loc
, pos
+1, results
, builders
);
657 unsigned int num_results
= results
.size();
658 this->try_suffix_expansion (s
, p
, loc
, pos
, results
);
660 // XXX: how to correctly report alternatives + position numbers
661 // for alias suffixes? file a separate PR to address the issue
662 if (! loc
->optional
&& num_results
== results
.size())
664 // We didn't find any alias suffixes (since the size of the
665 // result vector didn't change). Throw an error.
666 string sugs
= suggest_functors(s
, loc
->components
[pos
]->functor
);
667 throw SEMANTIC_ERROR (_F("probe point mismatch%s",
668 sugs
.empty() ? "" : (" (similar: " + sugs
+ ")").c_str()),
669 loc
->components
[pos
]->tok
);
675 match_node::suggest_functors(systemtap_session
& s
, string functor
)
677 // only use prefix if globby (and prefix is non-empty)
678 size_t glob
= functor
.find('*');
679 if (glob
!= string::npos
&& glob
!= 0)
684 // PR18577: There isn't any point in generating a suggestion list if
685 // we're not going to display it.
686 if ((s
.dump_mode
== systemtap_session::dump_matched_probes
687 || s
.dump_mode
== systemtap_session::dump_matched_probes_vars
)
691 set
<string
> functors
;
692 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
694 string ftor
= i
->first
.str();
695 if (ftor
.find('(') != string::npos
) // trim any parameter
696 ftor
.erase(ftor
.find('('));
697 functors
.insert(ftor
);
699 return levenshtein_suggest(functor
, functors
, 5); // print top 5
703 match_node::try_suffix_expansion (systemtap_session
& s
,
704 probe
*p
, probe_point
*loc
, unsigned pos
,
705 vector
<derived_probe
*>& results
)
707 // PR12210: match alias suffixes. If the components thus far
708 // have been matched, but there is an additional unknown
709 // suffix, we have a potential alias suffix on our hands. We
710 // need to expand the preceding components as probe aliases,
711 // reattach the suffix, and re-run derive_probes() on the
712 // resulting expansion. This is done by the routine
713 // build_with_suffix().
715 if (strverscmp(s
.compatible
.c_str(), "2.0") >= 0)
717 // XXX: technically, param_map isn't used here. So don't
718 // bother actually assembling it unless some
719 // derived_probe_builder appears that actually takes
720 // suffixes *and* consults parameters (currently no such
722 literal_map_t param_map
;
723 // for (unsigned i=0; i<pos; i++)
724 // param_map[loc->components[i]->functor] = loc->components[i]->arg;
727 vector
<probe_point::component
*> suffix (loc
->components
.begin()+pos
,
728 loc
->components
.end());
730 // Multiple derived_probe_builders may be bound at a
731 // match_node due to the possibility of multiply defined
733 for (unsigned k
=0; k
< ends
.size(); k
++)
735 derived_probe_builder
*b
= ends
[k
];
738 b
->build_with_suffix (s
, p
, loc
, param_map
, results
, suffix
);
740 catch (const recursive_expansion_error
&e
)
743 throw semantic_error(e
);
745 catch (const semantic_error
&e
)
747 // Adjust source coordinate and re-throw:
749 throw semantic_error(e
.errsrc
, e
.what(), loc
->components
[pos
]->tok
);
757 match_node::build_no_more (systemtap_session
& s
)
759 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
760 i
->second
->build_no_more (s
);
761 for (unsigned k
=0; k
<ends
.size(); k
++)
763 derived_probe_builder
*b
= ends
[k
];
764 b
->build_no_more (s
);
769 match_node::dump (systemtap_session
&s
, const string
&name
)
771 // Dump this node, if it is complete.
772 for (unsigned k
=0; k
<ends
.size(); k
++)
774 // Don't print aliases at all (for now) until we can figure out how to determine whether
775 // the probes they resolve to are ok in unprivileged mode.
776 if (ends
[k
]->is_alias ())
779 // In unprivileged mode, don't show the probes which are not allowed for unprivileged
781 if (pr_contains (privilege
, s
.privilege
))
783 cout
<< name
<< endl
;
784 break; // we need only print one instance.
788 // Recursively dump the children of this node
792 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
794 i
->second
->dump (s
, name
+ dot
+ i
->first
.str());
799 // ------------------------------------------------------------------------
801 // ------------------------------------------------------------------------
803 struct alias_derived_probe
: public derived_probe
805 alias_derived_probe (probe
* base
, probe_point
*l
, const probe_alias
*a
,
806 const vector
<probe_point::component
*> *suffix
= 0);
807 ~alias_derived_probe();
809 void upchuck () { throw SEMANTIC_ERROR (_("inappropriate"), this->tok
); }
811 // Alias probes are immediately expanded to other derived_probe
812 // types, and are not themselves emitted or listed in
813 // systemtap_session.probes
815 void join_group (systemtap_session
&) { upchuck (); }
817 virtual const probe_alias
*get_alias () const { return alias
; }
818 virtual probe_point
*get_alias_loc () const { return alias_loc
; }
819 virtual probe_point
*sole_location () const;
822 const probe_alias
*alias
; // Used to check for recursion
823 probe_point
*alias_loc
; // Hack to recover full probe name
827 alias_derived_probe::alias_derived_probe(probe
*base
, probe_point
*l
,
828 const probe_alias
*a
,
829 const vector
<probe_point::component
*>
831 derived_probe (base
, l
), alias(a
)
833 // XXX pretty nasty -- this was cribbed from printscript() in main.cxx
834 assert (alias
->alias_names
.size() >= 1);
835 alias_loc
= new probe_point(*alias
->alias_names
[0]); // XXX: [0] is arbitrary; it would make just as much sense to collect all of the names
836 alias_loc
->well_formed
= true;
837 vector
<probe_point::component
*>::const_iterator it
;
838 for (it
= suffix
->begin(); it
!= suffix
->end(); ++it
)
840 alias_loc
->components
.push_back(*it
);
841 if (isglob((*it
)->functor
))
842 alias_loc
->well_formed
= false; // needs further derivation
846 alias_derived_probe::~alias_derived_probe ()
853 alias_derived_probe::sole_location () const
855 return const_cast<probe_point
*>(alias_loc
);
860 alias_expansion_builder::build(systemtap_session
& sess
,
862 probe_point
* location
,
863 literal_map_t
const & parameters
,
864 vector
<derived_probe
*> & finished_results
)
866 vector
<probe_point::component
*> empty_suffix
;
867 build_with_suffix (sess
, use
, location
, parameters
,
868 finished_results
, empty_suffix
);
872 alias_expansion_builder::build_with_suffix(systemtap_session
& sess
,
874 probe_point
* location
,
875 literal_map_t
const &,
876 vector
<derived_probe
*>
878 vector
<probe_point::component
*>
881 // Don't build the alias expansion if infinite recursion is detected.
882 if (checkForRecursiveExpansion (use
)) {
884 msg
<< _F("recursive loop in alias expansion of %s at %s",
885 lex_cast(*location
).c_str(), lex_cast(location
->components
.front()->tok
->location
).c_str());
886 // semantic_errors thrown here might be ignored, so we need a special class:
887 throw recursive_expansion_error (msg
.str());
888 // XXX The point of throwing this custom error is to suppress a
889 // cascade of "probe mismatch" messages that appear in addition to
890 // the error. The current approach suppresses most of the error
891 // cascade, but leaves one spurious error; in any case, the way
892 // this particular error is reported could be improved.
895 // We're going to build a new probe and wrap it up in an
896 // alias_expansion_probe so that the expansion loop recognizes it as
897 // such and re-expands its expansion.
899 alias_derived_probe
* n
= new alias_derived_probe (use
, location
/* soon overwritten */, this->alias
, &suffix
);
900 n
->body
= new block();
902 // The new probe gets a deep copy of the location list of the alias
903 // (with incoming condition joined) plus the suffix (if any),
904 n
->locations
.clear();
905 for (unsigned i
=0; i
<alias
->locations
.size(); i
++)
907 probe_point
*pp
= new probe_point(*alias
->locations
[i
]);
908 pp
->components
.insert(pp
->components
.end(), suffix
.begin(), suffix
.end());
909 pp
->condition
= add_condition (pp
->condition
, location
->condition
);
910 n
->locations
.push_back(pp
);
913 // the token location of the alias,
914 n
->tok
= location
->components
.front()->tok
;
916 // and statements representing the concatenation of the alias'
917 // body with the use's.
919 // NB: locals are *not* copied forward, from either alias or
920 // use. The expansion should have its locals re-inferred since
921 // there's concatenated code here and we only want one vardecl per
922 // resulting variable.
924 if (alias
->epilogue_style
)
925 n
->body
= new block (use
->body
, alias
->body
);
927 n
->body
= new block (alias
->body
, use
->body
);
929 unsigned old_num_results
= finished_results
.size();
930 // If expanding for an alias suffix, be sure to pass on any errors
931 // to the caller instead of printing them in derive_probes():
932 derive_probes (sess
, n
, finished_results
, location
->optional
, !suffix
.empty());
934 // Check whether we resolved something. If so, put the
935 // whole library into the queue if not already there.
936 if (finished_results
.size() > old_num_results
)
938 stapfile
*f
= alias
->tok
->location
.file
;
939 if (find (sess
.files
.begin(), sess
.files
.end(), f
)
941 sess
.files
.push_back (f
);
946 alias_expansion_builder::checkForRecursiveExpansion (probe
*use
)
948 // Collect the derivation chain of this probe.
949 vector
<probe
*>derivations
;
950 use
->collect_derivation_chain (derivations
);
952 // Check all probe points in the alias expansion against the currently-being-expanded probe point
953 // of each of the probes in the derivation chain, looking for a match. This
954 // indicates infinite recursion.
955 // The first element of the derivation chain will be the derived_probe representing 'use', so
956 // start the search with the second element.
957 assert (derivations
.size() > 0);
958 assert (derivations
[0] == use
);
959 for (unsigned d
= 1; d
< derivations
.size(); ++d
) {
960 if (use
->get_alias() == derivations
[d
]->get_alias())
961 return true; // recursion detected
967 // ------------------------------------------------------------------------
969 // ------------------------------------------------------------------------
971 // The match-and-expand loop.
973 derive_probes (systemtap_session
& s
,
974 probe
*p
, vector
<derived_probe
*>& dps
,
978 // We need a static to track whether the current probe is optional so that
979 // even if we recurse into derive_probes with optional = false, errors will
980 // still be ignored. The undo_parent_optional bool ensures we reset the
981 // static at the same level we had it set.
982 static bool parent_optional
= false;
983 bool undo_parent_optional
= false;
985 if (optional
&& !parent_optional
)
987 parent_optional
= true;
988 undo_parent_optional
= true;
991 vector
<semantic_error
> optional_errs
;
993 for (unsigned i
= 0; i
< p
->locations
.size(); ++i
)
995 set
<string
> builders
;
996 assert_no_interrupts();
998 probe_point
*loc
= p
->locations
[i
];
1001 clog
<< "derive-probes (location #" << i
<< "): " << *loc
<< " of " << *p
->tok
<< endl
;
1005 unsigned num_atbegin
= dps
.size();
1009 s
.pattern_root
->find_and_build (s
, p
, loc
, 0, dps
, builders
); // <-- actual derivation!
1011 catch (const semantic_error
& e
)
1013 if (!loc
->optional
&& !parent_optional
)
1014 throw semantic_error(e
);
1015 else /* tolerate failure for optional probe */
1017 // remember err, we will print it (in catch block) if any
1018 // non-optional loc fails to resolve
1019 semantic_error
err(ERR_SRC
, _("while resolving probe point"),
1020 loc
->components
[0]->tok
, NULL
, &e
);
1021 optional_errs
.push_back(err
);
1026 unsigned num_atend
= dps
.size();
1028 if (! (loc
->optional
||parent_optional
) && // something required, but
1029 num_atbegin
== num_atend
) // nothing new derived!
1030 throw SEMANTIC_ERROR (_("no match"));
1032 if (loc
->sufficient
&& (num_atend
> num_atbegin
))
1036 clog
<< "Probe point ";
1037 p
->locations
[i
]->print(clog
);
1038 clog
<< " sufficient, skipped";
1039 for (unsigned j
= i
+1; j
< p
->locations
.size(); ++j
)
1042 p
->locations
[j
]->print(clog
);
1046 break; // we need not try to derive for any other locations
1049 catch (const semantic_error
& e
)
1051 // The rethrow_errors parameter lets the caller decide an
1052 // alternative to printing the error. This is necessary when
1053 // calling derive_probes() recursively during expansion of
1054 // an alias with suffix -- any message printed here would
1055 // point to the alias declaration and not the invalid suffix
1056 // usage, so the caller needs to catch the error themselves
1057 // and print a more appropriate message.
1060 throw semantic_error(e
);
1062 // Only output in dump mode if -vv is supplied:
1063 else if (!s
.dump_mode
|| (s
.verbose
> 1))
1065 // print this one manually first because it's more important than
1066 // the optional errs
1067 semantic_error
err(ERR_SRC
, _("while resolving probe point"),
1068 loc
->components
[0]->tok
, NULL
, &e
);
1069 // provide some details about which builders were tried
1070 if (s
.verbose
> 0 && !builders
.empty())
1073 for (auto it
= builders
.begin(); it
!= builders
.end(); ++it
)
1075 if (it
!= builders
.begin())
1079 semantic_error
err2(ERR_SRC
, _F("resolution failed in %s", msg
.c_str()));
1080 err2
.set_chain(err
);
1081 s
.print_error(err2
);
1088 // print optional errs accumulated while visiting other probe points
1089 for (vector
<semantic_error
>::const_iterator it
= optional_errs
.begin();
1090 it
!= optional_errs
.end(); ++it
)
1098 if (undo_parent_optional
)
1100 parent_optional
= false;
1106 // ------------------------------------------------------------------------
1108 // Indexable usage checks
1111 struct symbol_fetcher
1112 : public throwing_visitor
1116 symbol_fetcher (symbol
*&sym
): sym(sym
)
1119 void visit_symbol (symbol
* e
)
1124 void visit_arrayindex (arrayindex
* e
)
1126 e
->base
->visit (this);
1129 void throwone (const token
* t
)
1131 throw SEMANTIC_ERROR (_("Expecting symbol or array index expression"), t
);
1136 get_symbol_within_expression (expression
*e
)
1139 symbol_fetcher
fetcher(sym
);
1140 e
->visit (&fetcher
);
1141 return sym
; // NB: may be null!
1145 get_symbol_within_indexable (indexable
*ix
)
1147 symbol
*array
= NULL
;
1148 hist_op
*hist
= NULL
;
1149 classify_indexable(ix
, array
, hist
);
1153 return get_symbol_within_expression (hist
->stat
);
1156 struct mutated_var_collector
1157 : public traversing_visitor
1159 set
<vardecl
*> * mutated_vars
;
1161 mutated_var_collector (set
<vardecl
*> * mm
)
1165 void visit_assignment(assignment
* e
)
1167 if (e
->type
== pe_stats
&& e
->op
== "<<<")
1169 vardecl
*vd
= get_symbol_within_expression (e
->left
)->referent
;
1171 mutated_vars
->insert (vd
);
1173 traversing_visitor::visit_assignment(e
);
1176 void visit_arrayindex (arrayindex
*e
)
1178 if (is_active_lvalue (e
))
1181 if (e
->base
->is_symbol (sym
))
1182 mutated_vars
->insert (sym
->referent
);
1184 throw SEMANTIC_ERROR(_("Assignment to read-only histogram bucket"), e
->tok
);
1186 traversing_visitor::visit_arrayindex (e
);
1191 struct no_var_mutation_during_iteration_check
1192 : public traversing_visitor
1194 systemtap_session
& session
;
1195 map
<functiondecl
*,set
<vardecl
*> *> & function_mutates_vars
;
1196 vector
<vardecl
*> vars_being_iterated
;
1198 no_var_mutation_during_iteration_check
1199 (systemtap_session
& sess
,
1200 map
<functiondecl
*,set
<vardecl
*> *> & fmv
)
1201 : session(sess
), function_mutates_vars (fmv
)
1204 void visit_arrayindex (arrayindex
*e
)
1206 if (is_active_lvalue(e
))
1208 vardecl
*vd
= get_symbol_within_indexable (e
->base
)->referent
;
1211 for (unsigned i
= 0; i
< vars_being_iterated
.size(); ++i
)
1213 vardecl
*v
= vars_being_iterated
[i
];
1216 string err
= _F("variable '%s' modified during 'foreach' iteration",
1217 v
->unmangled_name
.to_string().c_str());
1218 session
.print_error (SEMANTIC_ERROR (err
, e
->tok
));
1223 traversing_visitor::visit_arrayindex (e
);
1226 void visit_functioncall (functioncall
* e
)
1228 for (unsigned fd
= 0; fd
< e
->referents
.size(); fd
++)
1230 map
<functiondecl
*,set
<vardecl
*> *>::const_iterator i
1231 = function_mutates_vars
.find (e
->referents
[fd
]);
1233 if (i
!= function_mutates_vars
.end())
1235 for (unsigned j
= 0; j
< vars_being_iterated
.size(); ++j
)
1237 vardecl
*m
= vars_being_iterated
[j
];
1238 if (i
->second
->find (m
) != i
->second
->end())
1240 string err
= _F("function call modifies var '%s' during 'foreach' iteration",
1241 m
->unmangled_name
.to_string().c_str());
1242 session
.print_error (SEMANTIC_ERROR (err
, e
->tok
));
1248 traversing_visitor::visit_functioncall (e
);
1251 void visit_foreach_loop(foreach_loop
* s
)
1253 vardecl
*vd
= get_symbol_within_indexable (s
->base
)->referent
;
1256 vars_being_iterated
.push_back (vd
);
1258 traversing_visitor::visit_foreach_loop (s
);
1261 vars_being_iterated
.pop_back();
1266 // ------------------------------------------------------------------------
1268 struct stat_decl_collector
1269 : public traversing_visitor
1271 systemtap_session
& session
;
1273 stat_decl_collector(systemtap_session
& sess
)
1277 void visit_stat_op (stat_op
* e
)
1279 symbol
*sym
= get_symbol_within_expression (e
->stat
);
1280 statistic_decl new_stat
= statistic_decl();
1281 int bit_shift
= (e
->params
.size() == 0) ? 0 : e
->params
[0];
1282 int stat_op
= STAT_OP_NONE
;
1284 if ((bit_shift
< 0) || (bit_shift
> 62))
1285 throw SEMANTIC_ERROR (_F("bit shift (%d) out of range <0..62>",
1289 // The following helps to track which statistical operators are being
1290 // used with given global/local variable. This information later helps
1291 // to optimize the runtime behaviour.
1293 if (e
->ctype
== sc_count
)
1294 stat_op
= STAT_OP_COUNT
;
1295 else if (e
->ctype
== sc_sum
)
1296 stat_op
= STAT_OP_SUM
;
1297 else if (e
->ctype
== sc_min
)
1298 stat_op
= STAT_OP_MIN
;
1299 else if (e
->ctype
== sc_max
)
1300 stat_op
= STAT_OP_MAX
;
1301 else if (e
->ctype
== sc_average
)
1302 stat_op
= STAT_OP_AVG
;
1303 else if (e
->ctype
== sc_variance
)
1304 stat_op
= STAT_OP_VARIANCE
;
1306 new_stat
.bit_shift
= bit_shift
;
1307 new_stat
.stat_ops
|= stat_op
;
1309 map
<interned_string
, statistic_decl
>::iterator i
= session
.stat_decls
.find(sym
->name
);
1310 if (i
== session
.stat_decls
.end())
1311 session
.stat_decls
[sym
->name
] = new_stat
;
1314 i
->second
.stat_ops
|= stat_op
;
1316 // The @variance operator for given stat S (i.e. call to
1317 // _stp_stat_init()) is optionally parametrizeable
1318 // (@variance(S[, N]), where N is a bit shift (the default is
1319 // N=0). The bit_shift helps to improve precision if integer
1320 // arithemtic, namely divisions ().
1322 // Ref: https://en.wikipedia.org/wiki/Scale_factor_%28computer_science%29
1324 if (e
->tok
->content
!= "@variance")
1326 else if ((i
->second
.bit_shift
!= 0)
1327 && (i
->second
.bit_shift
!= bit_shift
))
1329 // FIXME: Support multiple co-declared bit shifts
1330 // (analogy to multiple co-declared histogram types)
1331 throw SEMANTIC_ERROR (_F("conflicting bit shifts declared (previously %d)",
1332 i
->second
.bit_shift
),
1337 i
->second
.bit_shift
= bit_shift
;
1342 void visit_foreach_loop (foreach_loop
* s
)
1347 classify_indexable (s
->base
, array
, hist
);
1349 if (array
&& array
->type
== pe_stats
1350 && s
->sort_direction
1351 && s
->sort_column
== 0)
1353 int stat_op
= STAT_OP_NONE
;
1355 switch (s
->sort_aggr
) {
1356 default: case sc_none
: case sc_count
: stat_op
= STAT_OP_COUNT
; break;
1357 case sc_sum
: stat_op
= STAT_OP_SUM
; break;
1358 case sc_min
: stat_op
= STAT_OP_MIN
; break;
1359 case sc_max
: stat_op
= STAT_OP_MAX
; break;
1360 case sc_average
: stat_op
= STAT_OP_AVG
; break;
1363 map
<interned_string
, statistic_decl
>::iterator i
1364 = session
.stat_decls
.find(array
->name
);
1366 if (i
== session
.stat_decls
.end())
1367 session
.stat_decls
[array
->name
] = statistic_decl(stat_op
);
1369 i
->second
.stat_ops
|= stat_op
;
1372 traversing_visitor::visit_foreach_loop (s
);
1375 void visit_assignment (assignment
* e
)
1379 symbol
*sym
= get_symbol_within_expression (e
->left
);
1380 if (session
.stat_decls
.find(sym
->name
) == session
.stat_decls
.end())
1381 session
.stat_decls
[sym
->name
] = statistic_decl();
1384 traversing_visitor::visit_assignment(e
);
1387 void visit_hist_op (hist_op
* e
)
1389 symbol
*sym
= get_symbol_within_expression (e
->stat
);
1390 statistic_decl new_stat
;
1392 if (e
->htype
== hist_linear
)
1394 new_stat
.type
= statistic_decl::linear
;
1395 assert (e
->params
.size() == 3);
1396 new_stat
.linear_low
= e
->params
[0];
1397 new_stat
.linear_high
= e
->params
[1];
1398 new_stat
.linear_step
= e
->params
[2];
1402 assert (e
->htype
== hist_log
);
1403 new_stat
.type
= statistic_decl::logarithmic
;
1404 assert (e
->params
.size() == 0);
1407 map
<interned_string
, statistic_decl
>::iterator i
= session
.stat_decls
.find(sym
->name
);
1408 if (i
== session
.stat_decls
.end())
1409 session
.stat_decls
[sym
->name
] = new_stat
;
1412 statistic_decl
& old_stat
= i
->second
;
1413 if (!(old_stat
== new_stat
))
1415 if (old_stat
.type
== statistic_decl::none
)
1417 i
->second
.type
= new_stat
.type
;
1418 i
->second
.linear_low
= new_stat
.linear_low
;
1419 i
->second
.linear_high
= new_stat
.linear_high
;
1420 i
->second
.linear_step
= new_stat
.linear_step
;
1424 // FIXME: Support multiple co-declared histogram types
1425 semantic_error
se(ERR_SRC
, _F("multiple histogram types declared on '%s'",
1426 sym
->name
.to_string().c_str()), e
->tok
);
1427 session
.print_error (se
);
1436 semantic_pass_stats (systemtap_session
& sess
)
1438 stat_decl_collector
sdc(sess
);
1440 for (map
<string
,functiondecl
*>::iterator it
= sess
.functions
.begin(); it
!= sess
.functions
.end(); it
++)
1441 it
->second
->body
->visit (&sdc
);
1443 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1444 sess
.probes
[i
]->body
->visit (&sdc
);
1446 for (unsigned i
= 0; i
< sess
.globals
.size(); ++i
)
1448 vardecl
*v
= sess
.globals
[i
];
1449 if (v
->type
== pe_stats
)
1452 if (sess
.stat_decls
.find(v
->name
) == sess
.stat_decls
.end())
1454 semantic_error
se(ERR_SRC
, _F("unable to infer statistic parameters for global '%s'",
1455 v
->unmangled_name
.to_string().c_str()));
1456 sess
.print_error (se
);
1461 return sess
.num_errors();
1464 // ------------------------------------------------------------------------
1466 // Enforce variable-related invariants: no modification of
1467 // a foreach()-iterated array.
1469 semantic_pass_vars (systemtap_session
& sess
)
1472 map
<functiondecl
*, set
<vardecl
*> *> fmv
;
1473 no_var_mutation_during_iteration_check
chk(sess
, fmv
);
1475 for (map
<string
,functiondecl
*>::iterator it
= sess
.functions
.begin(); it
!= sess
.functions
.end(); it
++)
1477 functiondecl
* fn
= it
->second
;
1480 set
<vardecl
*> * m
= new set
<vardecl
*>();
1481 mutated_var_collector
mc (m
);
1482 fn
->body
->visit (&mc
);
1487 for (map
<string
,functiondecl
*>::iterator it
= sess
.functions
.begin(); it
!= sess
.functions
.end(); it
++)
1489 functiondecl
* fn
= it
->second
;
1490 if (fn
->body
) fn
->body
->visit (&chk
);
1493 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1495 if (sess
.probes
[i
]->body
)
1496 sess
.probes
[i
]->body
->visit (&chk
);
1499 return sess
.num_errors();
1503 // ------------------------------------------------------------------------
1505 // Rewrite probe condition expressions into probe bodies. Tricky and
1506 // exciting business, this. This:
1508 // probe foo if (g1 || g2) { ... }
1509 // probe bar { ... g1 ++ ... }
1513 // probe foo { if (! (g1 || g2)) next; ... }
1514 // probe bar { ... g1 ++ ...;
1515 // if (g1 || g2) %{ enable_probe_foo %} else %{ disable_probe_foo %}
1518 // In other words, we perform two transformations:
1519 // (1) Inline probe condition into its body.
1520 // (2) For each probe that modifies a global var in use in any probe's
1521 // condition, re-evaluate those probes' condition at the end of that
1524 // Here, we do all of (1), and half of (2): we simply collect the dependency
1525 // info between probes, which the translator will use to emit the affected
1526 // probes' condition re-evaluation. The translator will also ensure that the
1527 // conditions are evaluated using the globals' starting values prior to any
1530 // Adds the condition expression to the front of the probe's body
1532 derived_probe_condition_inline (derived_probe
*p
)
1534 expression
* e
= p
->sole_location()->condition
;
1537 if_statement
*ifs
= new if_statement ();
1539 ifs
->thenblock
= new next_statement ();
1540 ifs
->thenblock
->tok
= e
->tok
;
1541 ifs
->elseblock
= NULL
;
1542 unary_expression
*notex
= new unary_expression ();
1544 notex
->tok
= e
->tok
;
1546 ifs
->condition
= notex
;
1547 p
->body
= new block (ifs
, p
->body
);
1551 semantic_pass_conditions (systemtap_session
& sess
)
1553 map
<derived_probe
*, set
<vardecl
*> > vars_read_in_cond
;
1554 map
<derived_probe
*, set
<vardecl
*> > vars_written_in_body
;
1556 // do a first pass through the probes to inline any condition, collect
1557 // globals being read
1558 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1560 if (pending_interrupts
) return 1;
1562 derived_probe
* p
= sess
.probes
[i
];
1563 expression
* e
= p
->sole_location()->condition
;
1567 varuse_collecting_visitor
vcv_cond(sess
);
1568 e
->visit (& vcv_cond
);
1570 if (!vcv_cond
.written
.empty())
1571 sess
.print_error (SEMANTIC_ERROR (_("probe condition must not "
1572 "modify any variables"),
1574 else if (vcv_cond
.embedded_seen
)
1575 sess
.print_error (SEMANTIC_ERROR (_("probe condition must not "
1576 "include impure embedded-C"),
1579 derived_probe_condition_inline(p
);
1581 if (! vcv_cond
.read
.empty()) { // insert only if nonempty
1582 vars_read_in_cond
[p
].insert(vcv_cond
.read
.begin(),
1583 vcv_cond
.read
.end());
1588 // skip all the rest of this processing if there are no conditions
1589 // that relate to state (global variables) at all
1590 if (sess
.verbose
> 2)
1591 clog
<< "number of probes with global-variable conditions: "
1592 << vars_read_in_cond
.size() << endl
;
1593 if (vars_read_in_cond
.empty())
1596 // do a second pass to see what probes write to any globals
1597 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1599 if (pending_interrupts
) return 1;
1601 derived_probe
* p
= sess
.probes
[i
];
1603 varuse_collecting_visitor
vcv_body(sess
);
1604 p
->body
->visit (& vcv_body
);
1606 vars_written_in_body
[p
].insert(vcv_body
.written
.begin(),
1607 vcv_body
.written
.end());
1610 // do a third pass to collect affected probes
1611 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1613 if (pending_interrupts
) return 1;
1615 derived_probe
*p
= sess
.probes
[i
];
1617 // for each variable this probe modifies...
1618 set
<vardecl
*>::const_iterator var
;
1619 for (var
= vars_written_in_body
[p
].begin();
1620 var
!= vars_written_in_body
[p
].end(); ++var
)
1622 // collect probes which could be affected
1623 for (unsigned j
= 0; j
< sess
.probes
.size(); ++j
)
1625 if (vars_read_in_cond
[sess
.probes
[j
]].count(*var
))
1627 if (!p
->probes_with_affected_conditions
.count(sess
.probes
[j
]))
1629 p
->probes_with_affected_conditions
.insert(sess
.probes
[j
]);
1630 if (sess
.verbose
> 2)
1631 clog
<< "probe " << i
<< " can affect condition of "
1632 "probe " << j
<< endl
;
1639 // PR18115: We create a begin probe which is artificially registered as
1640 // affecting every other probe. This will serve as the initializer so that
1641 // other probe types with false conditions can be skipped (or registered as
1642 // disabled) during module initialization.
1644 set
<derived_probe
*> targets
;
1645 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1646 if (!vars_read_in_cond
[sess
.probes
[i
]].empty())
1647 targets
.insert(sess
.probes
[i
]);
1649 if (!targets
.empty())
1651 stringstream
ss("probe begin {}");
1653 // no good token to choose here... let's just use the condition expression
1654 // of one of the probes as the token
1655 const token
*tok
= (*targets
.begin())->sole_location()->condition
->tok
;
1657 probe
*p
= parse_synthetic_probe(sess
, ss
, tok
);
1659 throw SEMANTIC_ERROR (_("can't create cond initializer probe"), tok
);
1661 vector
<derived_probe
*> dps
;
1662 derive_probes(sess
, p
, dps
);
1664 // there should only be one
1665 assert(dps
.size() == 1);
1667 derived_probe
* dp
= dps
[0];
1668 dp
->probes_with_affected_conditions
.insert(targets
.begin(),
1670 sess
.probes
.push_back (dp
);
1672 // no need to manually do symresolution since body is empty
1675 return sess
.num_errors();
1678 // ------------------------------------------------------------------------
1681 // Simple visitor that just goes through all embedded code blocks that
1682 // are available at the end all the optimizations to register any
1683 // relevant pragmas or other indicators found, so that session flags can
1684 // be set that can be inspected at translation time to trigger any
1685 // necessary initialization of code needed by the embedded code functions.
1687 // This is only for pragmas that don't have any other side-effect than
1688 // needing some initialization at module init time. Currently handles
1689 // /* pragma:vma */ /* pragma:unwind */ /* pragma:symbols */ /* pragma:lines */
1691 // /* pragma:uprobes */ is handled during the typeresolution_info pass.
1692 // /* pure */, /* unprivileged */. /* myproc-unprivileged */ and /* guru */
1693 // are handled by the varuse_collecting_visitor.
1695 struct embeddedcode_info
: public functioncall_traversing_visitor
1698 systemtap_session
& session
;
1699 void examine (const interned_string
&, const token
*tok
);
1702 embeddedcode_info (systemtap_session
& s
): session(s
) { }
1704 template <class Embeddish
> void examine (Embeddish e
, const token
*tok
);
1706 void visit_embeddedcode (embeddedcode
* c
) { examine (c
, c
->tok
); }
1707 void visit_embedded_expr (embedded_expr
* e
) { examine (e
, e
->tok
); }
1711 template <class Embeddish
>
1713 embeddedcode_info::examine (Embeddish e
, const token
*tok
)
1715 if (! vma_tracker_enabled(session
)
1716 && e
->tagged_p("/* pragma:vma */"))
1718 if (session
.verbose
> 2)
1719 clog
<< _F("Turning on task_finder vma_tracker, pragma:vma found in %s",
1720 current_function
->unmangled_name
.to_string().c_str()) << endl
;
1722 // PR15052: stapdyn doesn't have VMA-tracking yet.
1723 if (session
.runtime_usermode_p())
1724 throw SEMANTIC_ERROR(_("VMA-tracking is only supported by the kernel runtime (PR15052)"), tok
);
1726 enable_vma_tracker(session
);
1729 if (! session
.need_unwind
1730 && e
->tagged_p("/* pragma:unwind */"))
1732 if (session
.verbose
> 2)
1733 clog
<< _F("Turning on unwind support, pragma:unwind found in %s",
1734 current_function
->unmangled_name
.to_string().c_str()) << endl
;
1735 session
.need_unwind
= true;
1738 if (! session
.need_symbols
1739 && e
->tagged_p("/* pragma:symbols */"))
1741 if (session
.verbose
> 2)
1742 clog
<< _F("Turning on symbol data collecting, pragma:symbols found in %s",
1743 current_function
->unmangled_name
.to_string().c_str()) << endl
;
1744 session
.need_symbols
= true;
1747 if (! session
.need_lines
1748 && e
->tagged_p("/* pragma:lines */"))
1750 if (session
.verbose
> 2)
1751 clog
<< _F("Turning on debug line data collecting, pragma:lines found in %s",
1752 current_function
->unmangled_name
.to_string().c_str()) << endl
;
1753 session
.need_lines
= true;
1757 void embeddedcode_info_pass (systemtap_session
& s
)
1759 embeddedcode_info
eci (s
);
1760 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
1761 s
.probes
[i
]->body
->visit (& eci
);
1763 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
1764 it
!= s
.functions
.end(); it
++)
1765 it
->second
->body
->visit (& eci
);
1768 // ------------------------------------------------------------------------
1771 // Simple visitor that collects all the regular expressions in the
1772 // file and adds them to the session DFA table.
1774 struct regex_collecting_visitor
: public functioncall_traversing_visitor
1777 systemtap_session
& session
;
1780 regex_collecting_visitor (systemtap_session
& s
): session(s
) { }
1782 void visit_regex_query (regex_query
*q
) {
1783 functioncall_traversing_visitor::visit_regex_query (q
);
1785 string re
= q
->right
->value
;
1786 regex_to_stapdfa (&session
, re
, q
->right
->tok
);
1790 // Go through the regex match invocations and generate corresponding DFAs.
1791 int gen_dfa_table (systemtap_session
& s
)
1793 regex_collecting_visitor
rcv(s
);
1795 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
1799 s
.probes
[i
]->body
->visit (& rcv
);
1801 if (s
.probes
[i
]->sole_location()->condition
)
1802 s
.probes
[i
]->sole_location()->condition
->visit (& rcv
);
1804 catch (const semantic_error
& e
)
1810 return s
.num_errors();
1813 // ------------------------------------------------------------------------
1816 static int semantic_pass_symbols (systemtap_session
&);
1817 static int semantic_pass_optimize1 (systemtap_session
&);
1818 static int semantic_pass_optimize2 (systemtap_session
&);
1819 static int semantic_pass_types (systemtap_session
&);
1820 static int semantic_pass_vars (systemtap_session
&);
1821 static int semantic_pass_stats (systemtap_session
&);
1822 static int semantic_pass_conditions (systemtap_session
&);
1825 struct expression_build_no_more_visitor
: public expression_visitor
1827 // Clear extra details from every expression, like DWARF type info, so that
1828 // builders can safely release them in build_no_more. From here on out,
1829 // we're back to basic types only.
1830 void visit_expression(expression
*e
)
1832 e
->type_details
.reset();
1837 build_no_more (systemtap_session
& s
)
1839 expression_build_no_more_visitor v
;
1841 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
1842 s
.probes
[i
]->body
->visit(&v
);
1844 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
1845 it
!= s
.functions
.end(); it
++)
1846 it
->second
->body
->visit(&v
);
1848 // Inform all derived_probe builders that we're done with
1849 // all resolution, so it's time to release caches.
1850 s
.pattern_root
->build_no_more (s
);
1855 // Link up symbols to their declarations. Set the session's
1856 // files/probes/functions/globals vectors from the transitively
1857 // reached set of stapfiles in s.library_files, starting from
1858 // s.user_file. Perform automatic tapset inclusion and probe
1861 semantic_pass_symbols (systemtap_session
& s
)
1863 symresolution_info
sym (s
);
1865 // If we're listing functions, then we need to include all the files. Probe
1866 // aliases won't be visited/derived so all we gain are the functions, global
1867 // variables, and any real probes (e.g. begin probes). NB: type resolution for
1868 // a specific function arg may fail if it could only be determined from a
1869 // function call in one of the skipped aliases.
1870 if (s
.dump_mode
== systemtap_session::dump_functions
)
1872 s
.files
.insert(s
.files
.end(), s
.library_files
.begin(),
1873 s
.library_files
.end());
1875 else if (!s
.user_files
.empty())
1877 // Normal run: seed s.files with user_files and let it grow through the
1878 // find_* functions. NB: s.files can grow during this iteration, so
1879 // size() can return gradually increasing numbers.
1880 s
.files
.insert (s
.files
.end(), s
.user_files
.begin(), s
.user_files
.end());
1883 for (unsigned i
= 0; i
< s
.files
.size(); i
++)
1885 assert_no_interrupts();
1886 stapfile
* dome
= s
.files
[i
];
1888 // Pass 1: add globals and functions to systemtap-session master list,
1889 // so the find_* functions find them
1891 // NB: tapset global/function definitions may duplicate or conflict
1892 // with those already in s.globals/functions. We need to deconflict
1895 // PR24239: don't transcribe s.files .globals or .functions into
1896 // s.globals or s.functions here. Instead, symresolution_info::find_*
1897 // will have already done that, for only those functions / globals
1898 // that are actually transitively referenced from the end-user script.
1900 // except in dump_* modes ... then we need to copy over the goods
1901 // regardless of transitive referencing.
1902 if (s
.dump_mode
== systemtap_session::dump_functions
)
1904 for (auto it
= dome
->functions
.begin(); it
!= dome
->functions
.end(); it
++)
1906 functiondecl
* v
= *it
;
1907 s
.functions
[v
->name
] = v
;
1913 for (auto it
= dome
->globals
.begin(); it
!= dome
->globals
.end(); it
++)
1914 if (std::find(s
.globals
.begin(), s
.globals
.end(), *it
) == s
.globals
.end())
1915 clog
<< "excluded unused global " << (*it
)->name
<< " from tapset " << dome
->name
<< endl
;
1917 for (auto it
= dome
->functions
.begin(); it
!= dome
->functions
.end(); it
++)
1918 if (s
.functions
.find((*it
)->name
) == s
.functions
.end())
1919 clog
<< "excluded unused function " << (*it
)->name
<< " from tapset " << dome
->name
<< endl
;
1922 // NB: embeds don't conflict with each other
1923 for (unsigned i
=0; i
<dome
->embeds
.size(); i
++)
1924 s
.embeds
.push_back (dome
->embeds
[i
]);
1926 // Pass 2: derive probes and resolve any further symbols in the
1929 for (unsigned i
=0; i
<dome
->probes
.size(); i
++)
1931 assert_no_interrupts();
1932 probe
* p
= dome
->probes
[i
];
1933 vector
<derived_probe
*> dps
;
1935 // much magic happens here: probe alias expansion, wildcard
1936 // matching, low-level derived_probe construction.
1937 derive_probes (s
, p
, dps
);
1939 for (unsigned j
=0; j
<dps
.size(); j
++)
1941 assert_no_interrupts();
1942 derived_probe
* dp
= dps
[j
];
1943 s
.probes
.push_back (dp
);
1945 // We don't perform the group join for the probe yet, as
1946 // some may be elided after optimization.
1950 clog
<< _("symbol resolution for derived-probe ");
1957 update_visitor_loop (s
, s
.code_filters
, dp
->body
);
1959 sym
.current_function
= 0;
1960 sym
.current_probe
= dp
;
1961 dp
->body
->visit (& sym
);
1963 // Process the probe-point condition expression.
1964 sym
.current_function
= 0;
1965 sym
.current_probe
= 0;
1966 if (dp
->sole_location()->condition
)
1967 dp
->sole_location()->condition
->visit (& sym
);
1969 catch (const semantic_error
& e
)
1976 // Pass 3: process functions - incl. the synthetic ones,
1977 // so s.functions[] rather than dome->functions[]
1979 for (auto it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
1981 assert_no_interrupts();
1982 functiondecl
* fd
= it
->second
;
1984 clog
<< _("symbol resolution for function ") << fd
->name
<< endl
;
1988 update_visitor_loop (s
, s
.code_filters
, fd
->body
);
1990 sym
.current_function
= fd
;
1991 sym
.current_probe
= 0;
1992 fd
->body
->visit (& sym
);
1994 catch (const semantic_error
& e
)
2001 if(s
.systemtap_v_check
){
2002 for(unsigned i
=0;i
<s
.globals
.size();i
++){
2003 if(s
.globals
[i
]->systemtap_v_conditional
)
2004 s
.print_warning(_("This global uses tapset constructs that are dependent on systemtap version"), s
.globals
[i
]->tok
);
2007 for(map
<string
, functiondecl
*>::const_iterator i
=s
.functions
.begin();i
!= s
.functions
.end();++i
){
2008 if(i
->second
->systemtap_v_conditional
)
2009 s
.print_warning(_("This function uses tapset constructs that are dependent on systemtap version"), i
->second
->tok
);
2012 for(unsigned i
=0;i
<s
.probes
.size();i
++){
2013 vector
<probe
*> sysvc
;
2014 s
.probes
[i
]->collect_derivation_chain(sysvc
);
2015 for(unsigned j
=0;j
<sysvc
.size();j
++){
2016 if(sysvc
[j
]->systemtap_v_conditional
)
2017 s
.print_warning(_("This probe uses tapset constructs that are dependent on systemtap version"), sysvc
[j
]->tok
);
2018 if(sysvc
[j
]->get_alias() && sysvc
[j
]->get_alias()->systemtap_v_conditional
)
2019 s
.print_warning(_("This alias uses tapset constructs that are dependent on systemtap version"), sysvc
[j
]->get_alias()->tok
);
2024 return s
.num_errors(); // all those print_error calls
2028 // Keep unread global variables for probe end value display.
2029 void add_global_var_display (systemtap_session
& s
)
2031 // Don't generate synthetic end probes when in listing mode; it would clutter
2032 // up the list of probe points with "end ...". In fact, don't bother in any
2033 // dump mode at all, since it'll never be used.
2034 if (s
.dump_mode
) return;
2036 // The bpf runtime currently lacks support for foreach statements which
2037 // this function might generate.
2038 if (s
.runtime_mode
== systemtap_session::bpf_runtime
) return;
2040 // User has specified not to display unread global variables.
2041 if (s
.no_global_var_display
) return;
2043 varuse_collecting_visitor
vut(s
);
2045 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
2047 s
.probes
[i
]->body
->visit (& vut
);
2049 if (s
.probes
[i
]->sole_location()->condition
)
2050 s
.probes
[i
]->sole_location()->condition
->visit (& vut
);
2053 for (unsigned g
=0; g
< s
.globals
.size(); g
++)
2055 vardecl
* l
= s
.globals
[g
];
2056 if ((vut
.read
.find (l
) != vut
.read
.end()
2057 && vut
.used
.find (l
) != vut
.used
.end())
2058 || vut
.written
.find (l
) == vut
.written
.end())
2061 // Don't generate synthetic end probes for unread globals
2062 // that were synthesized or declared only within tapsets.
2063 // (RHBZ 468139), but rather only within the end-user script.
2068 bool tapset_global
= false;
2069 for (size_t m
=0; m
< s
.library_files
.size(); m
++)
2071 for (size_t n
=0; n
< s
.library_files
[m
]->globals
.size(); n
++)
2073 if (l
->name
== s
.library_files
[m
]->globals
[n
]->name
)
2074 {tapset_global
= true; break;}
2081 code
<< "probe end {" << endl
;
2083 string format
= l
->unmangled_name
;
2086 string foreach_value
;
2087 if (!l
->index_types
.empty())
2089 // Add index values to the printf format, and prepare
2090 // a simple list of indexes for passing around elsewhere
2092 for (size_t i
= 0; i
< l
->index_types
.size(); ++i
)
2099 indexes
+= "__idx" + lex_cast(i
);
2100 if (l
->index_types
[i
] == pe_string
)
2101 format
+= "\\\"%#s\\\"";
2107 // Iterate over all indexes in the array, sorted by decreasing value
2108 code
<< "foreach (";
2109 if (l
->type
!= pe_stats
)
2111 foreach_value
= "__val";
2112 code
<< foreach_value
<< " = ";
2114 code
<< "[" << indexes
<< "] in " << l
->unmangled_name
<< "-)" << endl
;
2116 else if (l
->type
== pe_stats
)
2118 // PR7053: Check scalar globals for empty aggregate
2119 code
<< "if (@count(" << l
->unmangled_name
<< ") == 0)" << endl
;
2120 code
<< "printf(\"" << l
->unmangled_name
<< " @count=0x0\\n\")" << endl
;
2121 code
<< "else" << endl
;
2124 static const string stats
[] = { "@count", "@min", "@max", "@sum", "@avg" };
2125 const string stats_format
=
2126 (strverscmp(s
.compatible
.c_str(), "1.4") >= 0) ? "%#d" : "%#x";
2128 // Fill in the printf format for values
2129 if (l
->type
== pe_stats
)
2130 for (size_t i
= 0; i
< sizeof(stats
)/sizeof(stats
[0]); ++i
)
2131 format
+= " " + stats
[i
] + "=" + stats_format
;
2132 else if (l
->type
== pe_string
)
2133 format
+= "=\\\"%#s\\\"";
2137 // If l->type is pe_long, we need to differentiate between pointers and non-pointers.
2139 string specifier
= "=%d";
2141 if (l
->type_details
!= NULL
&& l
->type_details
->id() != 0)
2143 exp_type_dwarf
* type
= (exp_type_dwarf
*) l
->type_details
.get();
2145 if (type
->is_pointer
|| dwarf_tag(&type
->die
) == DW_TAG_pointer_type
)
2149 format
+= specifier
;
2155 // Output the actual printf
2156 code
<< "printf (\"" << format
<< "\"";
2158 // Feed indexes to the printf, and include them in the value
2159 string value
= !foreach_value
.empty() ? foreach_value
: string(l
->unmangled_name
);
2160 if (!l
->index_types
.empty())
2162 code
<< "," << indexes
;
2163 if (foreach_value
.empty())
2164 value
+= "[" + indexes
+ "]";
2167 // Feed the actual values to the printf
2168 if (l
->type
== pe_stats
)
2169 for (size_t i
= 0; i
< sizeof(stats
)/sizeof(stats
[0]); ++i
)
2170 code
<< "," << stats
[i
] << "(" << value
<< ")";
2172 code
<< "," << value
;
2173 code
<< ")" << endl
;
2176 code
<< "}" << endl
;
2178 probe
*p
= parse_synthetic_probe (s
, code
, l
->tok
);
2180 throw SEMANTIC_ERROR (_("can't create global var display"), l
->tok
);
2182 vector
<derived_probe
*> dps
;
2183 derive_probes (s
, p
, dps
);
2184 for (unsigned i
= 0; i
< dps
.size(); i
++)
2186 derived_probe
* dp
= dps
[i
];
2187 s
.probes
.push_back (dp
);
2190 // Repopulate symbol and type info
2191 symresolution_info
sym (s
);
2192 sym
.current_function
= 0;
2193 sym
.current_probe
= dp
;
2194 dp
->body
->visit (& sym
);
2197 semantic_pass_types(s
);
2198 // Mark that variable is read
2199 vut
.read
.insert (l
);
2203 static void gen_monitor_data(systemtap_session
& s
)
2209 v
->unmangled_name
= v
->name
= "__global___monitor_module_start";
2212 v
->synthetic
= true;
2213 s
.globals
.push_back(v
);
2215 ec
= new embeddedcode
;
2216 ec
->code
= "#define STAP_MONITOR_READ 8192\n"
2217 "static char _monitor_buf[STAP_MONITOR_READ];";
2218 s
.embeds
.push_back(ec
);
2220 functiondecl
* fd
= new functiondecl
;
2221 fd
->synthetic
= true;
2222 fd
->unmangled_name
= fd
->name
= "__private___monitor_data_function_probes";
2223 fd
->type
= pe_string
;
2226 v
->unmangled_name
= v
->name
= "index";
2227 fd
->formal_args
.push_back(v
);
2228 ec
= new embeddedcode
;
2230 code
= "/* unprivileged */ /* pure */"
2231 "const struct stap_probe *const p = &stap_probes[STAP_ARG_index];\n"
2232 "if (likely (probe_timing(STAP_ARG_index))) {\n"
2233 "struct stat_data *stats = _stp_stat_get (probe_timing(STAP_ARG_index), 0);\n"
2234 "if (stats->count) {\n"
2235 "int64_t avg = _stp_div64 (NULL, stats->sum, stats->count);\n"
2236 "snprintf(_monitor_buf, STAP_MONITOR_READ,\n"
2237 "\"\\\"index\\\": %zu, \\\"state\\\": \\\"%s\\\", \\\"hits\\\": %lld, "
2238 "\\\"min\\\": %lld, \\\"avg\\\": %lld, \\\"max\\\": %lld, \",\n"
2239 "p->index, p->cond_enabled ? \"on\" : \"off\", (long long) stats->count,\n"
2240 "(long long) stats->min, (long long) avg, (long long) stats->max);\n"
2242 "snprintf(_monitor_buf, STAP_MONITOR_READ,\n"
2243 "\"\\\"index\\\": %zu, \\\"state\\\": \\\"%s\\\", \\\"hits\\\": %d, "
2244 "\\\"min\\\": %d, \\\"avg\\\": %d, \\\"max\\\": %d, \",\n"
2245 "p->index, p->cond_enabled ? \"on\" : \"off\", 0, 0, 0, 0);}}\n"
2246 "STAP_RETURN(_monitor_buf);\n";
2249 s
.functions
[fd
->name
] = fd
;
2251 stringstream probe_code
;
2252 probe_code
<< "probe begin {" << endl
;
2253 probe_code
<< "__monitor_module_start = jiffies()" << endl
;
2254 probe_code
<< "}" << endl
;
2256 probe
* p
= parse_synthetic_probe(s
, probe_code
, 0);
2258 throw SEMANTIC_ERROR (_("can't create begin probe"), 0);
2260 vector
<derived_probe
*> dps
;
2261 derive_probes (s
, p
, dps
);
2263 derived_probe
* dp
= dps
[0];
2264 s
.probes
.push_back (dp
);
2267 // Repopulate symbol info
2268 symresolution_info
sym (s
);
2269 sym
.current_function
= 0;
2270 sym
.current_probe
= dp
;
2271 dp
->body
->visit (&sym
);
2274 static void monitor_mode_read(systemtap_session
& s
)
2276 if (!s
.monitor
) return;
2278 gen_monitor_data(s
);
2282 unsigned long rough_max_json_size
= 100 +
2283 s
.globals
.size() * 100 +
2284 s
.probes
.size() * 200;
2286 code
<< "probe procfs(\"monitor_status\").read.maxsize(" << rough_max_json_size
<< ") {" << endl
;
2287 code
<< "try {"; // absorb .= overflows!
2288 code
<< "elapsed = (jiffies()-__monitor_module_start)/HZ()" << endl
;
2289 code
<< "hrs = elapsed/3600; mins = elapsed%3600/60; secs = elapsed%3600%60;" << endl
;
2290 code
<< "$value .= sprintf(\"{\\n\")" << endl
;
2291 code
<< "$value .= sprintf(\"\\\"uptime\\\": \\\"%02d:%02d:%02d\\\",\\n\", hrs, mins, secs)" << endl
;
2292 code
<< "$value .= sprintf(\"\\\"uid\\\": \\\"%d\\\",\\n\", uid())" << endl
;
2293 code
<< "$value .= sprintf(\"\\\"memory\\\": \\\"%s\\\",\\n\", module_size())" << endl
;
2294 code
<< "$value .= sprintf(\"\\\"module_name\\\": \\\"%s\\\",\\n\", module_name())" << endl
;
2296 code
<< "$value .= sprintf(\"\\\"globals\\\": {\\n\")" << endl
;
2297 for (auto it
= s
.globals
.cbegin(); it
!= s
.globals
.cend(); ++it
)
2299 if ((*it
)->synthetic
) continue;
2301 if (it
!= s
.globals
.cbegin())
2302 code
<< "$value .= sprintf(\",\\n\")" << endl
;
2304 code
<< "$value .= sprintf(\"\\\"%s\\\":\", \"" << (*it
)->unmangled_name
<< "\")" << endl
;
2305 if ((*it
)->arity
== 0)
2307 if ((*it
)->type
== pe_stats
)
2308 code
<< "$value .= sprintf(\"\\\"%d(count)\\\"\", @count(" << (*it
)->name
<< "))" << endl
;
2309 else if ((*it
)->type
== pe_string
)
2310 code
<< "$value .= string_quoted(sprintf(\"\\\"%s\\\"\"," << (*it
)->name
<< "))" << endl
;
2312 code
<< "$value .= string_quoted(sprint(" << (*it
)->name
<< "))" << endl
;
2314 else if ((*it
)->arity
> 0)
2315 code
<< "$value .= sprintf(\"\\\"[%d]\\\"\", " << (*it
)->maxsize
<< ")" << endl
;
2317 code
<< "$value .= sprintf(\"\\n},\\n\")" << endl
;
2319 code
<< "$value .= sprintf(\"\\\"probe_list\\\": [\\n\")" << endl
;
2320 for (auto it
= s
.probes
.cbegin(); it
!= s
.probes
.cend(); ++it
)
2322 if ((*it
)->synthetic
) continue;
2324 if (it
!= s
.probes
.cbegin())
2325 code
<< "$value .= sprintf(\",\\n\")" << endl
;
2327 istringstream
probe_point((*it
)->sole_location()->str());
2329 probe_point
>> name
;
2330 /* Escape quotes once for systemtap parser and once more for json parser */
2331 name
= lex_cast_qstring(lex_cast_qstring(name
));
2333 code
<< "$value .= sprintf(\"{%s\", __private___monitor_data_function_probes("
2334 << it
-s
.probes
.begin() << "))" << endl
;
2335 code
<< "$value .= sprintf(\"\\\"name\\\": %s}\", " << name
<< ")" << endl
;
2337 code
<< "$value .= sprintf(\"\\n],\\n\")" << endl
;
2339 code
<< "$value .= sprintf(\"}\\n\")" << endl
;
2341 code
<< "} catch(ex) { warn(\"JSON construction error: \" . ex) }" << endl
;
2342 code
<< "}" << endl
;
2343 probe
* p
= parse_synthetic_probe(s
, code
, 0);
2345 throw SEMANTIC_ERROR (_("can't create procfs probe"), 0);
2347 vector
<derived_probe
*> dps
;
2348 derive_probes (s
, p
, dps
);
2350 derived_probe
* dp
= dps
[0];
2351 s
.probes
.push_back (dp
);
2354 // Repopulate symbol info
2355 symresolution_info
sym (s
);
2356 sym
.current_function
= 0;
2357 sym
.current_probe
= dp
;
2358 dp
->body
->visit (&sym
);
2360 // Resolve types for variables used in the new procfs probe
2361 semantic_pass_types(s
);
2364 static void monitor_mode_write(systemtap_session
& s
)
2366 if (!s
.monitor
) return;
2368 for (auto it
= s
.probes
.cbegin(); it
!= s
.probes
.cend(); ++it
)
2370 vardecl
* v
= new vardecl
;
2371 v
->unmangled_name
= v
->name
= "__monitor_" + lex_cast(it
-s
.probes
.begin()) + "_enabled";
2372 v
->tok
= (*it
)->tok
;
2373 v
->set_arity(0, (*it
)->tok
);
2375 v
->init
= new literal_number(1);
2376 v
->synthetic
= true;
2377 s
.globals
.push_back(v
);
2379 symbol
* sym
= new symbol
;
2380 sym
->name
= v
->name
;
2382 sym
->type
= pe_long
;
2385 if ((*it
)->sole_location()->condition
)
2387 logical_and_expr
*e
= new logical_and_expr
;
2392 e
->right
= (*it
)->sole_location()->condition
;
2393 (*it
)->sole_location()->condition
= e
;
2397 (*it
)->sole_location()->condition
= sym
;
2403 code
<< "probe procfs(\"monitor_control\").write {" << endl
;
2405 code
<< "if ($value == \"clear\") {";
2406 for (auto it
= s
.globals
.cbegin(); it
!= s
.globals
.cend(); ++it
)
2410 if (v
->synthetic
) continue;
2412 if (v
->arity
== 0 && v
->init
)
2414 if (v
->type
== pe_long
)
2416 literal_number
* ln
= dynamic_cast<literal_number
*>(v
->init
);
2418 throw SEMANTIC_ERROR (_("expected literal number"), 0);
2419 code
<< v
->name
<< " = " << ln
->value
<< endl
;
2421 else if (v
->type
== pe_string
)
2423 literal_string
* ln
= dynamic_cast<literal_string
*>(v
->init
);
2425 throw SEMANTIC_ERROR (_("expected literal string"), 0);
2426 code
<< v
->name
<< " = " << lex_cast_qstring(ln
->value
) << endl
;
2431 // For scalar elements with no initial values, we reset to 0 or empty as
2432 // done with arrays and aggregates.
2433 code
<< "delete " << v
->name
<< endl
;
2437 code
<< "} else if ($value == \"resume\") {" << endl
;
2438 for (auto it
= s
.probes
.cbegin(); it
!= s
.probes
.cend(); ++it
)
2440 code
<< " __monitor_" << it
-s
.probes
.begin() << "_enabled" << " = 1" << endl
;
2443 code
<< "} else if ($value == \"pause\") {" << endl
;
2444 for (auto it
= s
.probes
.cbegin(); it
!= s
.probes
.cend(); ++it
)
2446 code
<< " __monitor_" << it
-s
.probes
.begin() << "_enabled" << " = 0" << endl
;
2448 code
<< "} else if ($value == \"quit\") {" << endl
;
2449 code
<< " exit()" << endl
;
2452 for (auto it
= s
.probes
.cbegin(); it
!= s
.probes
.cend(); ++it
)
2454 code
<< " if ($value == \"" << it
-s
.probes
.begin() << "\")"
2455 << " __monitor_" << it
-s
.probes
.begin() << "_enabled" << " ^= 1" << endl
;
2458 code
<< "}" << endl
;
2460 probe
* p
= parse_synthetic_probe(s
, code
, 0);
2462 throw SEMANTIC_ERROR (_("can't create procfs probe"), 0);
2464 vector
<derived_probe
*> dps
;
2465 derive_probes (s
, p
, dps
);
2467 derived_probe
* dp
= dps
[0];
2468 s
.probes
.push_back (dp
);
2471 // Repopulate symbol info
2472 symresolution_info
sym (s
, /* omniscient-unmangled */ true);
2473 sym
.current_function
= 0;
2474 sym
.current_probe
= dp
;
2475 dp
->body
->visit (&sym
);
2478 static void setup_timeout(systemtap_session
& s
)
2480 if (!s
.timeout
) return;
2483 code
<< "probe timer.ms(" << s
.timeout
<< ") {exit()}";
2484 probe
* p
= parse_synthetic_probe(s
, code
, 0);
2486 throw SEMANTIC_ERROR (_("can't create timer probe"), 0);
2488 vector
<derived_probe
*> dps
;
2489 derive_probes (s
, p
, dps
);
2491 derived_probe
* dp
= dps
[0];
2492 s
.probes
.push_back (dp
);
2495 // Repopulate symbol info
2496 symresolution_info
sym (s
);
2497 sym
.current_function
= 0;
2498 sym
.current_probe
= dp
;
2499 dp
->body
->visit (&sym
);
2503 semantic_pass (systemtap_session
& s
)
2509 // FIXME: interactive mode, register_library_aliases handles
2510 // both aliases from library files *and* user scripts. It would
2511 // be nice to have them in separate lists and register them
2513 s
.register_library_aliases();
2514 register_standard_tapsets(s
);
2516 if (rc
== 0) setup_timeout(s
);
2517 if (rc
== 0) rc
= semantic_pass_symbols (s
);
2518 if (rc
== 0) monitor_mode_write (s
);
2519 if (rc
== 0) rc
= semantic_pass_conditions (s
);
2520 if (rc
== 0) rc
= semantic_pass_optimize1 (s
);
2521 if (rc
== 0) rc
= semantic_pass_types (s
);
2522 if (rc
== 0) rc
= gen_dfa_table(s
);
2523 if (rc
== 0) add_global_var_display (s
);
2524 if (rc
== 0) monitor_mode_read(s
);
2525 if (rc
== 0) rc
= semantic_pass_optimize2 (s
);
2526 if (rc
== 0) rc
= semantic_pass_vars (s
);
2527 if (rc
== 0) rc
= semantic_pass_stats (s
);
2528 if (rc
== 0) embeddedcode_info_pass (s
);
2530 catch (const semantic_error
& e
)
2536 bool no_primary_probes
= true;
2537 for (unsigned i
= 0; i
< s
.probes
.size(); i
++)
2538 if (s
.is_primary_probe(s
.probes
[i
]))
2539 no_primary_probes
= false;
2541 if (s
.num_errors() == 0 && no_primary_probes
&& !s
.dump_mode
)
2543 s
.print_error(SEMANTIC_ERROR(_("no probes found")));
2550 // NB: listing mode only cares whether we have any probes,
2551 // so all previous error conditions are disregarded.
2552 if (s
.dump_mode
== systemtap_session::dump_matched_probes
||
2553 s
.dump_mode
== systemtap_session::dump_matched_probes_vars
)
2554 rc
= no_primary_probes
;
2556 // If we're dumping functions, only error out if no functions were found
2557 if (s
.dump_mode
== systemtap_session::dump_functions
)
2558 rc
= s
.functions
.empty();
2564 // ------------------------------------------------------------------------
2565 // semantic processing: symbol resolution
2568 symresolution_info::symresolution_info (systemtap_session
& s
, bool omniscient_unmangled
):
2569 session (s
), unmangled_p(omniscient_unmangled
), current_function (0), current_probe (0)
2575 symresolution_info::visit_block (block
* e
)
2577 for (unsigned i
=0; i
<e
->statements
.size(); i
++)
2581 e
->statements
[i
]->visit (this);
2583 catch (const semantic_error
& e
)
2585 session
.print_error (e
);
2592 symresolution_info::visit_foreach_loop (foreach_loop
* e
)
2594 for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
2595 e
->indexes
[i
]->visit (this);
2596 for (unsigned i
=0; i
<e
->array_slice
.size(); i
++)
2597 if (e
->array_slice
[i
])
2598 e
->array_slice
[i
]->visit(this);
2600 symbol
*array
= NULL
;
2601 hist_op
*hist
= NULL
;
2602 classify_indexable (e
->base
, array
, hist
);
2606 if (!array
->referent
)
2608 vardecl
* d
= find_var (array
->name
, e
->indexes
.size (), array
->tok
);
2611 array
->referent
= d
;
2612 array
->name
= d
->name
;
2617 msg
<< _F("unresolved arity-%zu global array %s, missing global declaration?",
2618 e
->indexes
.size(), array
->name
.to_string().c_str());
2619 throw SEMANTIC_ERROR (msg
.str(), array
->tok
);
2623 if (!e
->array_slice
.empty() && e
->array_slice
.size() != e
->indexes
.size())
2626 msg
<< _F("unresolved arity-%zu global array %s, missing global declaration?",
2627 e
->array_slice
.size(), array
->name
.to_string().c_str());
2628 throw SEMANTIC_ERROR (msg
.str(), array
->tok
);
2638 e
->value
->visit (this);
2641 e
->limit
->visit (this);
2643 e
->block
->visit (this);
2648 delete_statement_symresolution_info
:
2649 public traversing_visitor
2651 symresolution_info
*parent
;
2653 delete_statement_symresolution_info (symresolution_info
*p
):
2657 void visit_arrayindex (arrayindex
* e
)
2659 parent
->visit_arrayindex(e
, true);
2662 void visit_functioncall (functioncall
* e
)
2664 parent
->visit_functioncall (e
);
2667 void visit_symbol (symbol
* e
)
2672 vardecl
* d
= parent
->find_var (e
->name
, -1, e
->tok
);
2676 throw SEMANTIC_ERROR (_("unresolved array in delete statement"), e
->tok
);
2681 symresolution_info::visit_delete_statement (delete_statement
* s
)
2683 delete_statement_symresolution_info
di (this);
2684 s
->value
->visit (&di
);
2689 symresolution_info::visit_symbol (symbol
* e
)
2694 vardecl
* d
= find_var (e
->name
, 0, e
->tok
);
2703 vardecl
* v
= new vardecl
;
2704 v
->unmangled_name
= v
->name
= e
->name
;
2706 v
->set_arity(0, e
->tok
);
2707 if (current_function
)
2708 current_function
->locals
.push_back (v
);
2709 else if (current_probe
)
2710 current_probe
->locals
.push_back (v
);
2712 // must be probe-condition expression
2713 throw SEMANTIC_ERROR (_("probe condition must not reference undeclared global"), e
->tok
);
2720 symresolution_info::visit_arrayindex (arrayindex
* e
)
2722 visit_arrayindex(e
, false);
2726 symresolution_info::visit_arrayindex (arrayindex
* e
, bool wildcard_ok
)
2728 for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
2730 // assuming that if NULL, it was originally a wildcard (*)
2731 if (e
->indexes
[i
] == NULL
)
2734 throw SEMANTIC_ERROR(_("wildcard not allowed in array index"), e
->tok
);
2737 e
->indexes
[i
]->visit (this);
2740 symbol
*array
= NULL
;
2741 hist_op
*hist
= NULL
;
2742 classify_indexable(e
->base
, array
, hist
);
2746 if (array
->referent
)
2749 vardecl
* d
= find_var (array
->name
, e
->indexes
.size (), array
->tok
);
2752 array
->referent
= d
;
2753 array
->name
= d
->name
;
2758 msg
<< _F("unresolved arity-%zu global array %s, missing global declaration?",
2759 e
->indexes
.size(), array
->name
.to_string().c_str());
2760 throw SEMANTIC_ERROR (msg
.str(), e
->tok
);
2772 symresolution_info::visit_array_in (array_in
* e
)
2774 visit_arrayindex(e
->operand
, true);
2779 symresolution_info::visit_embeddedcode (embeddedcode
* s
)
2781 // PR24239: must generate find_var references to globals
2782 // that are marked by pragma:{read|write}:var
2784 if (s
->code_referents
== s
->code
)
2785 return; // already analyzed
2790 pos
= s
->code
.find("/* pragma:read:", pos
);
2791 if (pos
== string::npos
)
2793 pos
+= strlen("/* pragma:read:");
2794 auto pos2
= s
->code
.find(" */", pos
);
2795 if (pos2
== string::npos
)
2797 auto var
= s
->code
.substr(pos
, pos2
-pos
);
2798 auto vd
= find_var(var
,-1,s
->tok
);
2800 throw SEMANTIC_ERROR (_F("unresolved pragma:read global %s", ((string
)var
).c_str()),
2802 s
->read_referents
.push_back(vd
);
2810 pos
= s
->code
.find("/* pragma:write:", pos
);
2811 if (pos
== string::npos
)
2813 pos
+= strlen("/* pragma:write:");
2814 auto pos2
= s
->code
.find(" */", pos
);
2815 if (pos2
== string::npos
)
2817 auto var
= s
->code
.substr(pos
, pos2
-pos
);
2818 auto vd
= find_var(var
,-1,s
->tok
);
2820 throw SEMANTIC_ERROR (_F("unresolved pragma:write global %s", ((string
)var
).c_str()),
2822 s
->write_referents
.push_back(vd
);
2826 s
->code_referents
= s
->code
; // flag this object as not needing resolution again
2827 // NB: why not a bool? sure, could do that, but this way we can detect subsequent
2828 // changes to the code object, and be ready to recompute. It's at least harmless.
2833 symresolution_info::visit_embedded_expr (embedded_expr
*e
)
2835 // PR24239: must generate find_var references to globals
2836 // that are marked by pragma:{read|write}:var
2838 if (e
->code_referents
== e
->code
)
2839 return; // already analyzed
2844 pos
= e
->code
.find("/* pragma:read:", pos
);
2845 if (pos
== string::npos
)
2847 pos
+= strlen("/* pragma:read:");
2848 auto pos2
= e
->code
.find(" */", pos
);
2849 if (pos2
== string::npos
)
2851 auto var
= e
->code
.substr(pos
, pos2
-pos
);
2852 auto vd
= find_var(var
,-1,e
->tok
);
2854 throw SEMANTIC_ERROR (_F("unresolved pragma:read global %s", ((string
)var
).c_str()),
2856 e
->read_referents
.push_back(vd
);
2864 pos
= e
->code
.find("/* pragma:write:", pos
);
2865 if (pos
== string::npos
)
2867 pos
+= strlen("/* pragma:write:");
2868 auto pos2
= e
->code
.find(" */", pos
);
2869 if (pos2
== string::npos
)
2871 auto var
= e
->code
.substr(pos
, pos2
-pos
);
2872 auto vd
= find_var(var
,-1,e
->tok
);
2874 throw SEMANTIC_ERROR (_F("unresolved pragma:write global %s", ((string
)var
).c_str()),
2876 e
->write_referents
.push_back(vd
);
2880 e
->code_referents
= e
->code
; // flag this object as not needing resolution again
2881 // NB: why not a bool? sure, could do that, but this way we can detect subsequent
2882 // changes to the code object, and be ready to recompute. It's at least harmless.
2887 symresolution_info::visit_functioncall (functioncall
* e
)
2889 // XXX: we could relax this, if we're going to examine the
2890 // vartracking data recursively. See testsuite/semko/fortytwo.stp.
2891 if (! (current_function
|| current_probe
))
2893 // must be probe-condition expression
2894 throw SEMANTIC_ERROR (_("probe condition must not reference function"), e
->tok
);
2897 for (unsigned i
=0; i
<e
->args
.size(); i
++)
2898 e
->args
[i
]->visit (this);
2900 // already resolved?
2901 if (!e
->referents
.empty())
2904 vector
<functiondecl
*> fds
= find_functions (e
, e
->function
, e
->args
.size (), e
->tok
);
2908 function_priority_order order
;
2909 stable_sort(e
->referents
.begin(), e
->referents
.end(), order
); // preserve declaration order
2910 e
->function
= e
->referents
[0]->name
;
2914 string sugs
= levenshtein_suggest(e
->function
, collect_functions(), 5); // print 5 funcs
2915 throw SEMANTIC_ERROR(_F("unresolved function%s",
2916 sugs
.empty() ? "" : (_(" (similar: ") + sugs
+ ")").c_str()),
2920 // In monitor mode, tapset functions used in the synthetic probe are not resolved and added
2921 // to the master list at the same time as the other functions so we must add them here to
2922 // allow the translator to generate the functions in the module.
2923 if (session
.monitor
&& session
.functions
.find(e
->function
) == session
.functions
.end())
2924 session
.functions
[e
->function
] = fds
[0]; // no overload
2927 /* find_var will return an argument other than zero if the name matches the var
2928 * name ie, if the current local name matches the name passed to find_var.
2929 * arity=-1 means any.
2932 symresolution_info::find_var (const string
& name
, int arity
, const token
* tok
)
2934 if (current_function
|| current_probe
)
2937 vector
<vardecl
*>& locals
= (current_function
?
2938 current_function
->locals
:
2939 current_probe
->locals
);
2942 for (unsigned i
=0; i
<locals
.size(); i
++)
2943 if (locals
[i
]->name
== name
)
2945 if (session
.verbose
> 2)
2946 cerr
<< _F(" local %s is already defined",
2947 name
.c_str()) << endl
;
2949 locals
[i
]->set_arity (arity
, tok
);
2954 // search function formal parameters (for scalars)
2955 if (arity
== 0 && current_function
)
2956 for (unsigned i
=0; i
<current_function
->formal_args
.size(); i
++)
2957 if (current_function
->formal_args
[i
]->name
== name
)
2959 // NB: no need to check arity here: formal args always scalar
2960 if (session
.verbose
> 2)
2961 cerr
<< _F(" local %s is formal parameter",
2962 name
.c_str()) << endl
;
2964 current_function
->formal_args
[i
]->set_arity (0, tok
);
2965 return current_function
->formal_args
[i
];
2968 // search processed globals
2969 string gname
, pname
;
2972 gname
= pname
= string(name
);
2976 gname
= "__global_" + string(name
);
2977 pname
= "__private_" + detox_path(tok
->location
.file
->name
) + string(name
);
2979 for (unsigned i
=0; i
<session
.globals
.size(); i
++)
2981 if ((session
.globals
[i
]->name
== name
&& startswith(name
, "__global_")) ||
2982 (session
.globals
[i
]->name
== gname
) ||
2983 (session
.globals
[i
]->name
== pname
))
2985 if (session
.verbose
> 2)
2986 cerr
<< _F(" global %s is already defined",
2987 name
.c_str()) << endl
;
2989 if (! session
.suppress_warnings
)
2991 vardecl
* v
= session
.globals
[i
];
2992 stapfile
* f
= tok
->location
.file
;
2993 if (!session
.is_user_file(f
->name
) && v
->tok
&& v
->tok
->location
.file
!= f
&& !f
->synthetic
)
2995 session
.print_warning (_F("cross-file global variable reference to %s from",
2996 lex_cast(*v
->tok
).c_str()), tok
);
2999 session
.globals
[i
]->set_arity (arity
, tok
);
3000 return session
.globals
[i
];
3004 // search chosen-tapset globals
3005 for (unsigned i
=0; i
<session
.files
.size(); i
++)
3007 stapfile
* f
= session
.files
[i
];
3008 for (unsigned j
=0; j
<f
->globals
.size(); j
++)
3010 vardecl
* g
= f
->globals
[j
];
3011 if ((g
->name
== gname
) ||
3012 (g
->name
== pname
)) // private global within tapset probe alias
3014 if (session
.verbose
> 2)
3015 cerr
<< _F(" global %s is defined in chosen-tapset-file %s",
3016 name
.c_str(), f
->name
.c_str()) << endl
;
3018 g
->set_arity (arity
, tok
);
3020 session
.globals
.push_back (g
);
3027 // search not-yet-chosen library globals
3028 for (unsigned i
=0; i
<session
.library_files
.size(); i
++)
3030 stapfile
* f
= session
.library_files
[i
];
3031 for (unsigned j
=0; j
<f
->globals
.size(); j
++)
3033 vardecl
* g
= f
->globals
[j
];
3034 if ((g
->name
== gname
) ||
3035 (g
->name
== pname
)) // private global within tapset probe alias
3037 if (session
.verbose
> 2)
3038 cerr
<< _F(" global %s is defined in new-tapset-file %s",
3039 name
.c_str(), f
->name
.c_str()) << endl
;
3041 g
->set_arity (arity
, tok
);
3043 assert (find (session
.files
.begin(), session
.files
.end(), f
) == session
.files
.end());
3044 session
.files
.push_back (f
);
3045 session
.globals
.push_back (g
);
3056 class functioncall_security_check
: public traversing_visitor
3058 systemtap_session
& session
;
3060 functiondecl
* current_function
;
3062 functioncall_security_check(systemtap_session
&s
, functioncall
* c
): session(s
),call(c
) {}
3063 void traverse (functiondecl
* d
)
3065 current_function
= d
;
3066 current_function
->body
->visit(this);
3069 void visit_embeddedcode (embeddedcode
*s
)
3071 // Don't allow embedded C functions in unprivileged mode unless
3072 // they are tagged with /* unprivileged */ or /* myproc-unprivileged */
3073 // or we're in a usermode runtime.
3074 if (! pr_contains (session
.privilege
, pr_stapdev
) &&
3075 ! pr_contains (session
.privilege
, pr_stapsys
) &&
3076 ! session
.runtime_usermode_p () &&
3077 ! s
->tagged_p ("/* unprivileged */") &&
3078 ! s
->tagged_p ("/* myproc-unprivileged */"))
3079 throw SEMANTIC_ERROR (_F("function may not be used when --privilege=%s is specified",
3080 pr_name (session
.privilege
)),
3081 current_function
->tok
);
3083 // Allow only /* bpf */ functions in bpf mode.
3084 if ((session
.runtime_mode
== systemtap_session::bpf_runtime
)
3085 != (s
->tagged_p ("/* bpf */")))
3087 if (session
.runtime_mode
== systemtap_session::bpf_runtime
)
3088 throw SEMANTIC_ERROR (_("function may not be used with bpf runtime"),
3089 current_function
->tok
);
3091 throw SEMANTIC_ERROR (_("function requires bpf runtime"),
3092 current_function
->tok
);
3095 // Don't allow /* guru */ functions unless caller is privileged.
3096 if (!call
->synthetic
&& !call
->tok
->location
.file
->privileged
&&
3097 s
->tagged_p ("/* guru */"))
3098 throw SEMANTIC_ERROR (_("function may not be used unless -g is specified"),
3104 vector
<functiondecl
*>
3105 symresolution_info::find_functions (functioncall
*call
, const string
& name
, unsigned arity
, const token
*tok
)
3107 vector
<functiondecl
*> functions
;
3108 functiondecl
* last
= 0; // used for error message
3112 // internal global functions bypassing the parser, such as __global_dwarf_tvar_[gs]et
3113 if ((session
.functions
.find(name
) != session
.functions
.end()) && startswith(name
, "__private_"))
3115 functiondecl
* fd
= session
.functions
[name
];
3116 assert (fd
->name
== name
);
3117 if (fd
->formal_args
.size() == arity
)
3118 functions
.push_back(fd
);
3123 // functions scanned by the parser are overloaded
3124 unsigned alternatives
= session
.overload_count
[name
];
3125 for (unsigned alt
= 0; alt
< alternatives
; alt
++)
3127 bool found
= false; // multiple inclusion guard
3128 string gname
= "__global_" + string(name
) + "__overload_" + lex_cast(alt
);
3129 string pname
= "__private_" + detox_path(tok
->location
.file
->name
) + string(name
) +
3130 "__overload_" + lex_cast(alt
);
3132 // tapset or user script global functions coming from the parser
3133 if (!found
&& session
.functions
.find(gname
) != session
.functions
.end())
3135 functiondecl
* fd
= session
.functions
[gname
];
3136 assert (fd
->name
== gname
);
3137 if (fd
->formal_args
.size() == arity
)
3139 functions
.push_back(fd
);
3146 // tapset or user script private functions coming from the parser
3147 if (!found
&& session
.functions
.find(pname
) != session
.functions
.end())
3149 functiondecl
* fd
= session
.functions
[pname
];
3150 assert (fd
->name
== pname
);
3151 if (fd
->formal_args
.size() == arity
)
3153 functions
.push_back(fd
);
3160 // search chosen-tapset-file functions
3161 for (unsigned i
=0; !found
&& i
<session
.files
.size(); i
++)
3163 stapfile
* f
= session
.files
[i
];
3164 for (unsigned j
=0; !found
&& j
<f
->functions
.size(); j
++)
3166 if ((f
->functions
[j
]->name
== gname
) ||
3167 (f
->functions
[j
]->name
== pname
))
3169 if (f
->functions
[j
]->formal_args
.size() == arity
)
3171 // put library into the queue if not already there
3172 if (session
.verbose
> 2)
3173 cerr
<< _F(" function %s is defined in chosen-tapset-file %s",
3174 name
.c_str(), f
->name
.c_str()) << endl
;
3176 functions
.push_back(f
->functions
[j
]);
3180 last
= f
->functions
[j
];
3185 // search not-yet-chosen library functions
3186 for (unsigned i
=0; !found
&& i
<session
.library_files
.size(); i
++)
3188 stapfile
* f
= session
.library_files
[i
];
3189 for (unsigned j
=0; !found
&& j
<f
->functions
.size(); j
++)
3191 if ((f
->functions
[j
]->name
== gname
) ||
3192 (f
->functions
[j
]->name
== pname
))
3194 if (f
->functions
[j
]->formal_args
.size() == arity
)
3196 // put library into the queue if not already there
3197 if (session
.verbose
> 2)
3198 cerr
<< _F(" function %s is defined in new-tapset-file %s",
3199 name
.c_str(), f
->name
.c_str()) << endl
;
3201 assert (find (session
.files
.begin(), session
.files
.end(), f
) == session
.files
.end());
3202 session
.files
.push_back (f
);
3204 functions
.push_back(f
->functions
[j
]);
3208 last
= f
->functions
[j
];
3214 // suggest last found function with matching name
3215 if (last
&& functions
.empty())
3217 throw SEMANTIC_ERROR(_F("arity mismatch found (function '%s' takes %zu args)",
3218 name
.c_str(), last
->formal_args
.size()), tok
, last
->tok
);
3221 // check every function for safety/security constraints
3222 functioncall_security_check
fsc(session
, call
);
3223 for (auto gi
= functions
.begin(); gi
!= functions
.end(); gi
++) {
3226 // record this as a used function for later sym resolution
3227 functiondecl
*f
= *gi
;
3228 const string
& fname
= f
->name
;
3229 functiondecl
*f2
= session
.functions
[fname
];
3231 session
.print_error (SEMANTIC_ERROR (_("conflicting functions"),
3233 session
.functions
[fname
] = f
;
3241 symresolution_info::collect_functions(void)
3245 for (map
<string
,functiondecl
*>::const_iterator it
= session
.functions
.begin();
3246 it
!= session
.functions
.end(); ++it
)
3247 funcs
.insert(it
->second
->unmangled_name
);
3249 // search library functions
3250 for (unsigned i
=0; i
<session
.library_files
.size(); i
++)
3252 stapfile
* f
= session
.library_files
[i
];
3253 for (unsigned j
=0; j
<f
->functions
.size(); j
++)
3254 if (! f
->functions
[j
]->name
.starts_with("__private_"))
3255 funcs
.insert(f
->functions
[j
]->unmangled_name
);
3261 // ------------------------------------------------------------------------
3265 // Do away with functiondecls that are never (transitively) called
3268 // PR24239: this will generally not trigger, since we avoid adding
3269 // uncalled functions to s.functions[].
3270 void semantic_pass_opt1 (systemtap_session
& s
, bool& relaxed_p
)
3272 functioncall_traversing_visitor ftv
;
3273 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
3275 s
.probes
[i
]->body
->visit (& ftv
);
3276 if (s
.probes
[i
]->sole_location()->condition
)
3277 s
.probes
[i
]->sole_location()->condition
->visit (& ftv
);
3279 vector
<functiondecl
*> new_unused_functions
;
3280 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
3282 functiondecl
* fd
= it
->second
;
3283 if (ftv
.seen
.find(fd
) == ftv
.seen
.end())
3285 if (! fd
->synthetic
&& s
.is_user_file(fd
->tok
->location
.file
->name
))
3286 s
.print_warning (_F("Eliding unused function '%s'",
3287 fd
->unmangled_name
.to_string().c_str()),
3289 // s.functions.erase (it); // NB: can't, since we're already iterating upon it
3290 new_unused_functions
.push_back (fd
);
3294 for (unsigned i
=0; i
<new_unused_functions
.size(); i
++)
3296 map
<string
,functiondecl
*>::iterator where
= s
.functions
.find (new_unused_functions
[i
]->name
);
3297 assert (where
!= s
.functions
.end());
3298 s
.functions
.erase (where
);
3299 if (s
.tapset_compile_coverage
)
3300 s
.unused_functions
.push_back (new_unused_functions
[i
]);
3305 // ------------------------------------------------------------------------
3307 // Do away with local & global variables that are never
3308 // written nor read.
3309 void semantic_pass_opt2 (systemtap_session
& s
, bool& relaxed_p
, unsigned iterations
)
3311 varuse_collecting_visitor
vut(s
);
3313 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
3315 s
.probes
[i
]->body
->visit (& vut
);
3317 if (s
.probes
[i
]->sole_location()->condition
)
3318 s
.probes
[i
]->sole_location()->condition
->visit (& vut
);
3321 // NB: Since varuse_collecting_visitor also traverses down
3322 // actually called functions, we don't need to explicitly
3323 // iterate over them. Uncalled ones should have been pruned
3326 // for (unsigned i=0; i<s.functions.size(); i++)
3327 // s.functions[i]->body->visit (& vut);
3329 // Now in vut.read/written, we have a mixture of all locals, globals
3331 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
3332 for (unsigned j
=0; j
<s
.probes
[i
]->locals
.size(); /* see below */)
3334 vardecl
* l
= s
.probes
[i
]->locals
[j
];
3336 // skip over "special" locals
3337 if (l
->synthetic
) { j
++; continue; }
3339 if (vut
.read
.find (l
) == vut
.read
.end() &&
3340 vut
.written
.find (l
) == vut
.written
.end())
3342 if (!l
->tok
->location
.file
->synthetic
&& s
.is_user_file(l
->tok
->location
.file
->name
))
3343 s
.print_warning (_F("Eliding unused variable '%s'",
3344 l
->unmangled_name
.to_string().c_str()),
3346 if (s
.tapset_compile_coverage
) {
3347 s
.probes
[i
]->unused_locals
.push_back
3348 (s
.probes
[i
]->locals
[j
]);
3350 s
.probes
[i
]->locals
.erase(s
.probes
[i
]->locals
.begin() + j
);
3352 // don't increment j
3356 if (vut
.written
.find (l
) == vut
.written
.end())
3357 if (iterations
== 0 && ! s
.suppress_warnings
)
3361 // like collect_functions()
3362 vector
<vardecl
*>::iterator it
;
3363 for (it
= s
.probes
[i
]->locals
.begin(); it
!= s
.probes
[i
]->locals
.end(); it
++)
3364 vars
.insert((*it
)->unmangled_name
);
3365 for (it
= s
.globals
.begin(); it
!= s
.globals
.end(); it
++)
3366 if (! (*it
)->unmangled_name
.starts_with("__private_"))
3367 vars
.insert((*it
)->unmangled_name
);
3369 vars
.erase(l
->name
);
3370 string sugs
= levenshtein_suggest(l
->name
, vars
, 5); // suggest top 5 vars
3371 s
.print_warning (_F("never-assigned local variable '%s'%s",
3372 l
->unmangled_name
.to_string().c_str(),
3373 (sugs
.empty() ? "" :
3374 (_(" (similar: ") + sugs
+ ")")).c_str()), l
->tok
);
3380 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
3382 functiondecl
*fd
= it
->second
;
3383 for (unsigned j
=0; j
<fd
->locals
.size(); /* see below */)
3385 vardecl
* l
= fd
->locals
[j
];
3386 if (vut
.read
.find (l
) == vut
.read
.end() &&
3387 vut
.written
.find (l
) == vut
.written
.end())
3389 if (!l
->tok
->location
.file
->synthetic
&& s
.is_user_file(l
->tok
->location
.file
->name
))
3390 s
.print_warning (_F("Eliding unused variable '%s'",
3391 l
->unmangled_name
.to_string().c_str()),
3393 if (s
.tapset_compile_coverage
) {
3394 fd
->unused_locals
.push_back (fd
->locals
[j
]);
3396 fd
->locals
.erase(fd
->locals
.begin() + j
);
3398 // don't increment j
3402 if (vut
.written
.find (l
) == vut
.written
.end())
3403 if (iterations
== 0 && ! s
.suppress_warnings
)
3406 vector
<vardecl
*>::iterator it
;
3407 for (it
= fd
->formal_args
.begin() ;
3408 it
!= fd
->formal_args
.end(); it
++)
3409 vars
.insert((*it
)->unmangled_name
);
3410 for (it
= fd
->locals
.begin(); it
!= fd
->locals
.end(); it
++)
3411 vars
.insert((*it
)->unmangled_name
);
3412 for (it
= s
.globals
.begin(); it
!= s
.globals
.end(); it
++)
3413 if (! (*it
)->unmangled_name
.starts_with("__private_"))
3414 vars
.insert((*it
)->unmangled_name
);
3416 vars
.erase(l
->name
);
3417 string sugs
= levenshtein_suggest(l
->name
, vars
, 5); // suggest top 5 vars
3418 s
.print_warning (_F("never-assigned local variable '%s'%s",
3419 l
->unmangled_name
.to_string().c_str(),
3420 (sugs
.empty() ? "" :
3421 (_(" (similar: ") + sugs
+ ")")).c_str()), l
->tok
);
3428 for (unsigned i
=0; i
<s
.globals
.size(); /* see below */)
3430 vardecl
* l
= s
.globals
[i
];
3431 if (vut
.read
.find (l
) == vut
.read
.end() &&
3432 vut
.written
.find (l
) == vut
.written
.end())
3434 if (!l
->tok
->location
.file
->synthetic
&& s
.is_user_file(l
->tok
->location
.file
->name
))
3435 s
.print_warning (_F("Eliding unused variable '%s'",
3436 l
->unmangled_name
.to_string().c_str()),
3438 if (s
.tapset_compile_coverage
) {
3439 s
.unused_globals
.push_back(s
.globals
[i
]);
3441 s
.globals
.erase(s
.globals
.begin() + i
);
3443 // don't increment i
3447 if (vut
.written
.find (l
) == vut
.written
.end() && ! l
->init
) // no initializer
3448 if (iterations
== 0 && ! s
.suppress_warnings
)
3450 // check if it was initialized on the command line via
3452 bool init_by_gopt
= false;
3453 string
init_prefix (l
->unmangled_name
.to_string() + "=");
3454 for (auto gi
= s
.globalopts
.begin(); gi
!= s
.globalopts
.end();
3456 if (! gi
->compare(0, init_prefix
.size(), init_prefix
))
3458 init_by_gopt
= true;
3464 for (auto it
= s
.globals
.begin(); it
!= s
.globals
.end();
3466 if (l
->name
!= (*it
)->unmangled_name
)
3467 if (! (*it
)->unmangled_name
.starts_with("__private_"))
3468 vars
.insert((*it
)->unmangled_name
);
3470 // suggest top 5 vars
3471 string sugs
= levenshtein_suggest(l
->name
, vars
, 5);
3472 s
.print_warning (_F("never-assigned global variable '%s'%s",
3473 l
->unmangled_name
.to_string().c_str(),
3474 (sugs
.empty() ? "" :
3475 (_(" (similar: ") + sugs
+ ")")).c_str()),
3486 // ------------------------------------------------------------------------
3488 struct dead_assignment_remover
: public update_visitor
3490 systemtap_session
& session
;
3492 const varuse_collecting_visitor
& vut
;
3494 dead_assignment_remover(systemtap_session
& s
, bool& r
,
3495 const varuse_collecting_visitor
& v
):
3496 update_visitor(s
.verbose
), session(s
), relaxed_p(r
), vut(v
) {}
3498 void visit_assignment (assignment
* e
);
3499 void visit_try_block (try_block
*s
);
3503 // symbol_fetcher augmented to allow target-symbol types, but NULLed.
3504 struct assignment_symbol_fetcher
3505 : public symbol_fetcher
3507 const token
* assignment_t
;
3509 assignment_symbol_fetcher (symbol
*&sym
, const token
* a_t
): symbol_fetcher(sym
),
3513 void visit_target_symbol (target_symbol
*)
3518 void visit_atvar_op (atvar_op
*)
3523 void visit_cast_op (cast_op
*)
3528 void visit_autocast_op (autocast_op
*)
3533 void visit_target_deref (target_deref
*)
3538 void visit_target_register (target_register
*)
3543 void throwone (const token
* t
)
3545 if (t
->type
== tok_operator
&& t
->content
== ".")
3546 // guess someone misused . in $foo->bar.baz expression
3547 // XXX why are we only checking this in lvalues?
3548 throw SEMANTIC_ERROR (_("Expecting lvalue for assignment, try -> instead"),
3551 throw SEMANTIC_ERROR (_("Expecting lvalue for assignment"), assignment_t
, t
);
3556 get_assignment_symbol_within_expression (expression
*e
, const token
*a_t
)
3559 assignment_symbol_fetcher
fetcher(sym
, a_t
);
3560 e
->visit (&fetcher
);
3561 return sym
; // NB: may be null!
3566 dead_assignment_remover::visit_assignment (assignment
* e
)
3571 symbol
* left
= get_assignment_symbol_within_expression (e
->left
, e
->tok
);
3572 if (left
) // not unresolved $target, so intended sideeffect may be elided
3574 vardecl
* leftvar
= left
->referent
;
3575 if (vut
.read
.find(leftvar
) == vut
.read
.end()) // var never read?
3577 // NB: Not so fast! The left side could be an array whose
3578 // index expressions may have side-effects. This would be
3579 // OK if we could replace the array assignment with a
3580 // statement-expression containing all the index expressions
3581 // and the rvalue... but we can't.
3582 // Another possibility is that we have an unread global variable
3583 // which are kept for probe end value display.
3585 bool is_global
= false;
3586 vector
<vardecl
*>::iterator it
;
3587 for (it
= session
.globals
.begin(); it
!= session
.globals
.end(); it
++)
3588 if (leftvar
->name
== (*it
)->name
)
3594 varuse_collecting_visitor
lvut(session
);
3595 e
->left
->visit (& lvut
);
3596 if (lvut
.side_effect_free () && !is_global
// XXX: use _wrt() once we track focal_vars
3597 && !leftvar
->synthetic
) // don't elide assignment to synthetic $context variables
3599 /* PR 1119: NB: This is not necessary here. A write-only
3600 variable will also be elided soon at the next _opt2 iteration.
3601 if (e->left->tok->location.file->name == session.user_file->name) // !tapset
3602 session.print_warning("eliding write-only ", *e->left->tok);
3605 if (!e
->left
->tok
->location
.file
->synthetic
&& session
.is_user_file(e
->left
->tok
->location
.file
->name
))
3606 session
.print_warning(_F("Eliding assignment to '%s'",
3607 leftvar
->unmangled_name
.to_string().c_str()), e
->tok
);
3608 provide (e
->right
); // goodbye assignment*
3619 dead_assignment_remover::visit_try_block (try_block
*s
)
3621 replace (s
->try_block
);
3622 if (s
->catch_error_var
)
3624 vardecl
* errvar
= s
->catch_error_var
->referent
;
3625 if (vut
.read
.find(errvar
) == vut
.read
.end()) // never read?
3627 if (session
.verbose
>2)
3628 clog
<< _F("Eliding unused error string catcher %s at %s",
3629 errvar
->unmangled_name
.to_string().c_str(),
3630 lex_cast(*s
->tok
).c_str()) << endl
;
3631 s
->catch_error_var
= 0;
3634 replace (s
->catch_block
);
3639 // Let's remove assignments to variables that are never read. We
3640 // rewrite "(foo = expr)" as "(expr)". This makes foo a candidate to
3641 // be optimized away as an unused variable, and expr a candidate to be
3642 // removed as a side-effect-free statement expression. Wahoo!
3643 void semantic_pass_opt3 (systemtap_session
& s
, bool& relaxed_p
)
3645 // Recompute the varuse data, which will probably match the opt2
3646 // copy of the computation, except for those totally unused
3647 // variables that opt2 removed.
3648 varuse_collecting_visitor
vut(s
);
3649 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
3650 s
.probes
[i
]->body
->visit (& vut
); // includes reachable functions too
3652 dead_assignment_remover
dar (s
, relaxed_p
, vut
);
3653 // This instance may be reused for multiple probe/function body trims.
3655 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
3656 dar
.replace (s
.probes
[i
]->body
);
3657 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
3658 it
!= s
.functions
.end(); it
++)
3659 dar
.replace (it
->second
->body
);
3660 // The rewrite operation is performed within the visitor.
3662 // XXX: we could also zap write-only globals here
3666 // ------------------------------------------------------------------------
3668 struct dead_stmtexpr_remover
: public update_visitor
3670 systemtap_session
& session
;
3672 set
<vardecl
*> focal_vars
; // vars considered subject to side-effects
3674 dead_stmtexpr_remover(systemtap_session
& s
, bool& r
):
3675 update_visitor(s
.verbose
), session(s
), relaxed_p(r
) {}
3677 void visit_block (block
*s
);
3678 void visit_try_block (try_block
*s
);
3679 void visit_null_statement (null_statement
*s
);
3680 void visit_if_statement (if_statement
* s
);
3681 void visit_foreach_loop (foreach_loop
*s
);
3682 void visit_for_loop (for_loop
*s
);
3683 // XXX: and other places where stmt_expr's might be nested
3685 void visit_expr_statement (expr_statement
*s
);
3690 dead_stmtexpr_remover::visit_null_statement (null_statement
*s
)
3693 if (session
.verbose
>2)
3694 clog
<< _("Eliding side-effect-free null statement ") << *s
->tok
<< endl
;
3701 dead_stmtexpr_remover::visit_block (block
*s
)
3703 vector
<statement
*> new_stmts
;
3704 for (unsigned i
=0; i
<s
->statements
.size(); i
++ )
3706 statement
* new_stmt
= require (s
->statements
[i
], true);
3709 // flatten nested blocks into this one
3710 block
*b
= dynamic_cast<block
*>(new_stmt
);
3713 if (session
.verbose
>2)
3714 clog
<< _("Flattening nested block ") << *b
->tok
<< endl
;
3715 new_stmts
.insert(new_stmts
.end(),
3716 b
->statements
.begin(), b
->statements
.end());
3720 new_stmts
.push_back (new_stmt
);
3723 if (new_stmts
.size() == 0)
3725 if (session
.verbose
>2)
3726 clog
<< _("Eliding side-effect-free empty block ") << *s
->tok
<< endl
;
3729 else if (new_stmts
.size() == 1)
3731 if (session
.verbose
>2)
3732 clog
<< _("Eliding side-effect-free singleton block ") << *s
->tok
<< endl
;
3733 provide (new_stmts
[0]);
3737 s
->statements
= new_stmts
;
3743 dead_stmtexpr_remover::visit_try_block (try_block
*s
)
3745 replace (s
->try_block
, true);
3746 replace (s
->catch_block
, true); // null catch{} is ok and useful
3747 if (s
->try_block
== 0)
3749 if (session
.verbose
>2)
3750 clog
<< _("Eliding empty try {} block ") << *s
->tok
<< endl
;
3758 dead_stmtexpr_remover::visit_if_statement (if_statement
*s
)
3760 replace (s
->thenblock
, true);
3761 replace (s
->elseblock
, true);
3763 if (s
->thenblock
== 0)
3765 if (s
->elseblock
== 0)
3767 // We may be able to elide this statement, if the condition
3768 // expression is side-effect-free.
3769 varuse_collecting_visitor
vct(session
);
3770 s
->condition
->visit(& vct
);
3771 if (vct
.side_effect_free ())
3773 if (session
.verbose
>2)
3774 clog
<< _("Eliding side-effect-free if statement ")
3776 s
= 0; // yeah, baby
3780 // We can still turn it into a simple expr_statement though...
3781 if (session
.verbose
>2)
3782 clog
<< _("Creating simple evaluation from if statement ")
3784 expr_statement
*es
= new expr_statement
;
3785 es
->value
= s
->condition
;
3786 es
->tok
= es
->value
->tok
;
3793 // For an else without a then, we can invert the condition logic to
3794 // avoid having a null statement in the thenblock
3795 if (session
.verbose
>2)
3796 clog
<< _("Inverting the condition of if statement ")
3798 unary_expression
*ue
= new unary_expression
;
3799 ue
->operand
= s
->condition
;
3800 ue
->tok
= ue
->operand
->tok
;
3803 s
->thenblock
= s
->elseblock
;
3811 dead_stmtexpr_remover::visit_foreach_loop (foreach_loop
*s
)
3813 replace (s
->block
, true);
3817 // XXX what if s->limit has side effects?
3818 // XXX what about s->indexes or s->value used outside the loop?
3819 if(session
.verbose
> 2)
3820 clog
<< _("Eliding side-effect-free foreach statement ") << *s
->tok
<< endl
;
3821 s
= 0; // yeah, baby
3827 dead_stmtexpr_remover::visit_for_loop (for_loop
*s
)
3829 replace (s
->block
, true);
3833 // We may be able to elide this statement, if the condition
3834 // expression is side-effect-free.
3835 varuse_collecting_visitor
vct(session
);
3836 if (s
->init
) s
->init
->visit(& vct
);
3837 s
->cond
->visit(& vct
);
3838 if (s
->incr
) s
->incr
->visit(& vct
);
3839 if (vct
.side_effect_free ())
3841 if (session
.verbose
>2)
3842 clog
<< _("Eliding side-effect-free for statement ") << *s
->tok
<< endl
;
3843 s
= 0; // yeah, baby
3847 // Can't elide this whole statement; put a null in there.
3848 s
->block
= new null_statement(s
->tok
);
3857 dead_stmtexpr_remover::visit_expr_statement (expr_statement
*s
)
3859 // Run a varuse query against the operand expression. If it has no
3860 // side-effects, replace the entire statement expression by a null
3861 // statement with the provide() call.
3863 // Unlike many other visitors, we do *not* traverse this outermost
3864 // one into the expression subtrees. There is no need - no
3865 // expr_statement nodes will be found there. (Function bodies
3866 // need to be visited explicitly by our caller.)
3868 // NB. While we don't share nodes in the parse tree, let's not
3869 // deallocate *s anyway, just in case...
3871 varuse_collecting_visitor
vut(session
);
3872 s
->value
->visit (& vut
);
3874 if (vut
.side_effect_free_wrt (focal_vars
))
3876 /* PR 1119: NB: this message is not a good idea here. It can
3877 name some arbitrary RHS expression of an assignment.
3878 if (s->value->tok->location.file->name == session.user_file->name) // not tapset
3879 session.print_warning("eliding never-assigned ", *s->value->tok);
3882 if (!s
->value
->tok
->location
.file
->synthetic
&& session
.is_user_file(s
->value
->tok
->location
.file
->name
))
3883 session
.print_warning("Eliding side-effect-free expression ", s
->tok
);
3885 // NB: this 0 pointer is invalid to leave around for any length of
3886 // time, but the parent parse tree objects above handle it.
3894 void semantic_pass_opt4 (systemtap_session
& s
, bool& relaxed_p
)
3896 // Finally, let's remove some statement-expressions that have no
3897 // side-effect. These should be exactly those whose private varuse
3898 // visitors come back with an empty "written" and "embedded" lists.
3900 dead_stmtexpr_remover
duv (s
, relaxed_p
);
3901 // This instance may be reused for multiple probe/function body trims.
3903 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
3905 assert_no_interrupts();
3907 derived_probe
* p
= s
.probes
[i
];
3909 duv
.focal_vars
.clear ();
3910 duv
.focal_vars
.insert (s
.globals
.begin(),
3912 duv
.focal_vars
.insert (p
->locals
.begin(),
3915 duv
.replace (p
->body
, true);
3919 p
->body
= new null_statement(p
->tok
);
3920 s
.empty_probes
.insert(p
);
3924 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
3926 assert_no_interrupts();
3928 functiondecl
* fn
= it
->second
;
3929 duv
.focal_vars
.clear ();
3930 duv
.focal_vars
.insert (fn
->locals
.begin(),
3932 duv
.focal_vars
.insert (fn
->formal_args
.begin(),
3933 fn
->formal_args
.end());
3934 duv
.focal_vars
.insert (s
.globals
.begin(),
3937 duv
.replace (fn
->body
, true);
3940 s
.print_warning (_F("side-effect-free function '%s'",
3941 fn
->unmangled_name
.to_string().c_str()),
3944 fn
->body
= new null_statement(fn
->tok
);
3946 // XXX: the next iteration of the outer optimization loop may
3947 // take this new null_statement away again, and thus give us a
3948 // fresh warning. It would be better if this fixup was performed
3949 // only after the relaxation iterations.
3950 // XXX: or else see bug #6469.
3956 // ------------------------------------------------------------------------
3958 // The goal of this visitor is to reduce top-level expressions in void context
3959 // into separate statements that evaluate each subcomponent of the expression.
3960 // The dead-statement-remover can later remove some parts if they have no side
3963 // All expressions must be overridden here so we never visit their subexpressions
3964 // accidentally. Thus, the only visited expressions should be value of an
3967 // For an expression to replace its expr_statement with something else, it will
3968 // let the new statement provide(), and then provide(0) for itself. The
3969 // expr_statement will take this as a sign that it's been replaced.
3970 struct void_statement_reducer
: public update_visitor
3972 systemtap_session
& session
;
3974 set
<vardecl
*> focal_vars
; // vars considered subject to side-effects
3976 void_statement_reducer(systemtap_session
& s
, bool& r
):
3977 update_visitor(s
.verbose
), session(s
), relaxed_p(r
) {}
3979 void visit_expr_statement (expr_statement
* s
);
3981 // expressions in conditional / loop controls are definitely a side effect,
3982 // but still recurse into the child statements
3983 void visit_if_statement (if_statement
* s
);
3984 void visit_for_loop (for_loop
* s
);
3985 void visit_foreach_loop (foreach_loop
* s
);
3987 // these expressions get rewritten into their statement equivalents
3988 void visit_logical_or_expr (logical_or_expr
* e
);
3989 void visit_logical_and_expr (logical_and_expr
* e
);
3990 void visit_ternary_expression (ternary_expression
* e
);
3992 // all of these can (usually) be reduced into simpler statements
3993 void visit_binary_expression (binary_expression
* e
);
3994 void visit_unary_expression (unary_expression
* e
);
3995 void visit_regex_query (regex_query
* e
); // XXX depends on subexpr extraction
3996 void visit_comparison (comparison
* e
);
3997 void visit_concatenation (concatenation
* e
);
3998 void visit_functioncall (functioncall
* e
);
3999 void visit_print_format (print_format
* e
);
4000 void visit_target_symbol (target_symbol
* e
);
4001 void visit_atvar_op (atvar_op
* e
);
4002 void visit_cast_op (cast_op
* e
);
4003 void visit_autocast_op (autocast_op
* e
);
4004 void visit_defined_op (defined_op
* e
);
4006 // these are a bit hairy to grok due to the intricacies of indexables and
4007 // stats, so I'm chickening out and skipping them...
4008 void visit_array_in (array_in
* e
) { provide (e
); }
4009 void visit_arrayindex (arrayindex
* e
) { provide (e
); }
4010 void visit_stat_op (stat_op
* e
) { provide (e
); }
4011 void visit_hist_op (hist_op
* e
) { provide (e
); }
4013 // these can't be reduced because they always have an effect
4014 void visit_return_statement (return_statement
* s
) { provide (s
); }
4015 void visit_delete_statement (delete_statement
* s
) { provide (s
); }
4016 void visit_pre_crement (pre_crement
* e
) { provide (e
); }
4017 void visit_post_crement (post_crement
* e
) { provide (e
); }
4018 void visit_assignment (assignment
* e
) { provide (e
); }
4021 void reduce_target_symbol (target_symbol
* e
, expression
* operand
=NULL
);
4026 void_statement_reducer::visit_expr_statement (expr_statement
* s
)
4028 replace (s
->value
, true);
4030 // if the expression provides 0, that's our signal that a new
4031 // statement has been provided, so we shouldn't provide this one.
4037 void_statement_reducer::visit_if_statement (if_statement
* s
)
4039 // s->condition is never void
4040 replace (s
->thenblock
);
4041 replace (s
->elseblock
);
4046 void_statement_reducer::visit_for_loop (for_loop
* s
)
4048 // s->init/cond/incr are never void
4054 void_statement_reducer::visit_foreach_loop (foreach_loop
* s
)
4056 // s->indexes/base/value/limit are never void
4062 void_statement_reducer::visit_logical_or_expr (logical_or_expr
* e
)
4064 // In void context, the evaluation of "a || b" is exactly like
4065 // "if (!a) b", so let's do that instead.
4067 if (session
.verbose
>2)
4068 clog
<< _("Creating if statement from unused logical-or ")
4071 if_statement
*is
= new if_statement
;
4075 unary_expression
*ue
= new unary_expression
;
4076 ue
->operand
= e
->left
;
4081 expr_statement
*es
= new expr_statement
;
4082 es
->value
= e
->right
;
4083 es
->tok
= es
->value
->tok
;
4093 void_statement_reducer::visit_logical_and_expr (logical_and_expr
* e
)
4095 // In void context, the evaluation of "a && b" is exactly like
4096 // "if (a) b", so let's do that instead.
4098 if (session
.verbose
>2)
4099 clog
<< _("Creating if statement from unused logical-and ")
4102 if_statement
*is
= new if_statement
;
4105 is
->condition
= e
->left
;
4107 expr_statement
*es
= new expr_statement
;
4108 es
->value
= e
->right
;
4109 es
->tok
= es
->value
->tok
;
4119 void_statement_reducer::visit_ternary_expression (ternary_expression
* e
)
4121 // In void context, the evaluation of "a ? b : c" is exactly like
4122 // "if (a) b else c", so let's do that instead.
4124 if (session
.verbose
>2)
4125 clog
<< _("Creating if statement from unused ternary expression ")
4128 if_statement
*is
= new if_statement
;
4130 is
->condition
= e
->cond
;
4132 expr_statement
*es
= new expr_statement
;
4133 es
->value
= e
->truevalue
;
4134 es
->tok
= es
->value
->tok
;
4137 es
= new expr_statement
;
4138 es
->value
= e
->falsevalue
;
4139 es
->tok
= es
->value
->tok
;
4149 void_statement_reducer::visit_binary_expression (binary_expression
* e
)
4151 // When the result of a binary operation isn't needed, it's just as good to
4152 // evaluate the operands as sequential statements in a block.
4154 if (session
.verbose
>2)
4155 clog
<< _("Eliding unused binary ") << *e
->tok
<< endl
;
4157 block
*b
= new block
;
4160 expr_statement
*es
= new expr_statement
;
4161 es
->value
= e
->left
;
4162 es
->tok
= es
->value
->tok
;
4163 b
->statements
.push_back(es
);
4165 es
= new expr_statement
;
4166 es
->value
= e
->right
;
4167 es
->tok
= es
->value
->tok
;
4168 b
->statements
.push_back(es
);
4177 void_statement_reducer::visit_unary_expression (unary_expression
* e
)
4179 // When the result of a unary operation isn't needed, it's just as good to
4180 // evaluate the operand directly
4182 if (session
.verbose
>2)
4183 clog
<< _("Eliding unused unary ") << *e
->tok
<< endl
;
4186 e
->operand
->visit(this);
4190 void_statement_reducer::visit_regex_query (regex_query
* e
)
4192 // TODOXXX After subexpression extraction is implemented,
4193 // regular expression matches *may* have side-effects in
4194 // terms of producing matched subexpressions, e.g.:
4196 // str =~ "pat"; println(matched(0));
4198 // It's debatable if we want to actually allow this, though.
4200 // Treat e as a unary expression on the left operand -- since the
4201 // right hand side must be a literal (as verified by the parser),
4202 // evaluating it never has side effects.
4204 if (session
.verbose
>2)
4205 clog
<< _("Eliding regex query ") << *e
->tok
<< endl
;
4208 e
->left
->visit(this);
4212 void_statement_reducer::visit_comparison (comparison
* e
)
4214 visit_binary_expression(e
);
4218 void_statement_reducer::visit_concatenation (concatenation
* e
)
4220 visit_binary_expression(e
);
4224 void_statement_reducer::visit_functioncall (functioncall
* e
)
4226 // If a function call is pure and its result ignored, we can elide the call
4227 // and just evaluate the arguments in sequence
4229 if (e
->args
.empty())
4235 bool side_effect_free
= true;
4236 for (unsigned i
= 0; i
< e
->referents
.size(); i
++)
4238 varuse_collecting_visitor
vut(session
);
4239 vut
.seen
.insert (e
->referents
[i
]);
4240 vut
.current_function
= e
->referents
[i
];
4241 e
->referents
[i
]->body
->visit (& vut
);
4242 if (!vut
.side_effect_free_wrt(focal_vars
))
4244 side_effect_free
= false;
4249 if (!side_effect_free
)
4255 if (session
.verbose
>2)
4256 clog
<< _("Eliding side-effect-free function call ") << *e
->tok
<< endl
;
4258 block
*b
= new block
;
4261 for (unsigned i
=0; i
<e
->args
.size(); i
++ )
4263 expr_statement
*es
= new expr_statement
;
4264 es
->value
= e
->args
[i
];
4265 es
->tok
= es
->value
->tok
;
4266 b
->statements
.push_back(es
);
4276 void_statement_reducer::visit_print_format (print_format
* e
)
4278 // When an sprint's return value is ignored, we can simply evaluate the
4279 // arguments in sequence
4281 if (e
->print_to_stream
|| !e
->args
.size())
4287 if (session
.verbose
>2)
4288 clog
<< _("Eliding unused print ") << *e
->tok
<< endl
;
4290 block
*b
= new block
;
4293 for (unsigned i
=0; i
<e
->args
.size(); i
++ )
4295 expr_statement
*es
= new expr_statement
;
4296 es
->value
= e
->args
[i
];
4297 es
->tok
= es
->value
->tok
;
4298 b
->statements
.push_back(es
);
4308 void_statement_reducer::reduce_target_symbol (target_symbol
* e
,
4309 expression
* operand
)
4311 // When the result of any target_symbol isn't needed, it's just as good to
4312 // evaluate the operand and any array indexes directly
4314 block
*b
= new block
;
4319 expr_statement
*es
= new expr_statement
;
4320 es
->value
= operand
;
4321 es
->tok
= es
->value
->tok
;
4322 b
->statements
.push_back(es
);
4325 for (unsigned i
=0; i
<e
->components
.size(); i
++ )
4327 if (e
->components
[i
].type
!= target_symbol::comp_expression_array_index
)
4330 expr_statement
*es
= new expr_statement
;
4331 es
->value
= e
->components
[i
].expr_index
;
4332 es
->tok
= es
->value
->tok
;
4333 b
->statements
.push_back(es
);
4343 void_statement_reducer::visit_atvar_op (atvar_op
* e
)
4345 if (session
.verbose
>2)
4346 clog
<< _("Eliding unused target symbol ") << *e
->tok
<< endl
;
4347 reduce_target_symbol (e
);
4351 void_statement_reducer::visit_target_symbol (target_symbol
* e
)
4353 if (session
.verbose
>2)
4354 clog
<< _("Eliding unused target symbol ") << *e
->tok
<< endl
;
4355 reduce_target_symbol (e
);
4359 void_statement_reducer::visit_cast_op (cast_op
* e
)
4361 if (session
.verbose
>2)
4362 clog
<< _("Eliding unused typecast ") << *e
->tok
<< endl
;
4363 reduce_target_symbol (e
, e
->operand
);
4367 void_statement_reducer::visit_autocast_op (autocast_op
* e
)
4369 if (session
.verbose
>2)
4370 clog
<< _("Eliding unused autocast ") << *e
->tok
<< endl
;
4371 reduce_target_symbol (e
, e
->operand
);
4376 void_statement_reducer::visit_defined_op (defined_op
* e
)
4378 // When the result of a @defined operation isn't needed, just elide
4379 // it entirely. Its operand $expression must already be
4380 // side-effect-free.
4382 if (session
.verbose
>2)
4383 clog
<< _("Eliding unused check ") << *e
->tok
<< endl
;
4390 void semantic_pass_opt5 (systemtap_session
& s
, bool& relaxed_p
)
4392 // Let's simplify statements with unused computed values.
4394 void_statement_reducer
vuv (s
, relaxed_p
);
4395 // This instance may be reused for multiple probe/function body trims.
4397 vuv
.focal_vars
.insert (s
.globals
.begin(), s
.globals
.end());
4399 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
4400 vuv
.replace (s
.probes
[i
]->body
);
4401 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
4402 it
!= s
.functions
.end(); it
++)
4403 vuv
.replace (it
->second
->body
);
4409 const_folder::get_literal(expression
*& e
,
4414 n
= (e
== last_number
) ? last_number
: NULL
;
4415 s
= (e
== last_string
) ? last_string
: NULL
;
4419 const_folder::get_number(expression
*& e
)
4422 return (e
== last_number
) ? last_number
: NULL
;
4426 const_folder::visit_literal_number (literal_number
* e
)
4433 const_folder::get_string(expression
*& e
)
4436 return (e
== last_string
) ? last_string
: NULL
;
4440 const_folder::visit_literal_string (literal_string
* e
)
4447 const_folder::visit_if_statement (if_statement
* s
)
4449 literal_number
* cond
= get_number (s
->condition
);
4452 replace (s
->thenblock
);
4453 replace (s
->elseblock
);
4458 if (session
.verbose
>2)
4459 clog
<< _F("Collapsing constant-%" PRIi64
" if-statement %s",
4460 cond
->value
, lex_cast(*s
->tok
).c_str()) << endl
;
4463 statement
* n
= cond
->value
? s
->thenblock
: s
->elseblock
;
4467 provide (new null_statement (s
->tok
));
4472 const_folder::visit_for_loop (for_loop
* s
)
4474 literal_number
* cond
= get_number (s
->cond
);
4475 if (!cond
|| cond
->value
)
4484 if (session
.verbose
>2)
4485 clog
<< _("Collapsing constantly-false for-loop ") << *s
->tok
<< endl
;
4489 s
->init
->visit (this);
4491 provide (new null_statement (s
->tok
));
4496 const_folder::visit_foreach_loop (foreach_loop
* s
)
4498 literal_number
* limit
= get_number (s
->limit
);
4499 if (!limit
|| limit
->value
> 0)
4501 for (unsigned i
= 0; i
< s
->indexes
.size(); ++i
)
4502 replace (s
->indexes
[i
]);
4510 if (session
.verbose
>2)
4511 clog
<< _("Collapsing constantly-limited foreach-loop ") << *s
->tok
<< endl
;
4514 provide (new null_statement (s
->tok
));
4519 const_folder::visit_binary_expression (binary_expression
* e
)
4522 literal_number
* left
= get_number (e
->left
);
4523 literal_number
* right
= get_number (e
->right
);
4525 if (right
&& !right
->value
&& (e
->op
== "/" || e
->op
== "%"))
4527 // Give divide-by-zero a chance to be optimized out elsewhere,
4528 // and if not it will be a runtime error anyway...
4536 value
= left
->value
+ right
->value
;
4537 else if (e
->op
== "-")
4538 value
= left
->value
- right
->value
;
4539 else if (e
->op
== "*")
4540 value
= left
->value
* right
->value
;
4541 else if (e
->op
== "&")
4542 value
= left
->value
& right
->value
;
4543 else if (e
->op
== "|")
4544 value
= left
->value
| right
->value
;
4545 else if (e
->op
== "^")
4546 value
= left
->value
^ right
->value
;
4547 else if (e
->op
== ">>")
4548 value
= left
->value
>> max(min(right
->value
, (int64_t)64), (int64_t)0);
4549 else if (e
->op
== "<<")
4550 value
= left
->value
<< max(min(right
->value
, (int64_t)64), (int64_t)0);
4551 else if (e
->op
== "/")
4552 value
= (left
->value
== LLONG_MIN
&& right
->value
== -1) ? LLONG_MIN
:
4553 left
->value
/ right
->value
;
4554 else if (e
->op
== "%")
4555 value
= (left
->value
== LLONG_MIN
&& right
->value
== -1) ? 0 :
4556 left
->value
% right
->value
;
4558 throw SEMANTIC_ERROR (_("unsupported binary operator ") + (string
)e
->op
);
4561 else if ((left
&& ((left
->value
== 0 && (e
->op
== "*" || e
->op
== "&" ||
4562 e
->op
== ">>" || e
->op
== "<<" )) ||
4563 (left
->value
==-1 && (e
->op
== "|" || e
->op
== ">>"))))
4565 (right
&& ((right
->value
== 0 && (e
->op
== "*" || e
->op
== "&")) ||
4566 (right
->value
== 1 && (e
->op
== "%")) ||
4567 (right
->value
==-1 && (e
->op
== "%" || e
->op
== "|")))))
4569 expression
* other
= left
? e
->right
: e
->left
;
4570 varuse_collecting_visitor
vu(session
);
4572 if (!vu
.side_effect_free())
4578 // we'll pass on type=pe_long inference to the expression
4579 if (other
->type
== pe_unknown
)
4580 other
->type
= pe_long
;
4581 else if (other
->type
!= pe_long
)
4583 // this mismatch was not caught in the initial type resolution pass,
4584 // generate a mismatch (left doesn't match right) error
4585 typeresolution_info
ti(session
);
4586 ti
.assert_resolvability
= true; // need this to get it throw errors
4587 ti
.mismatch_complexity
= 1; // also needed to throw errors
4592 value
= left
->value
;
4593 else if (e
->op
== "%")
4596 value
= right
->value
;
4599 else if ((left
&& ((left
->value
== 0 && (e
->op
== "+" || e
->op
== "|" ||
4601 (left
->value
== 1 && (e
->op
== "*")) ||
4602 (left
->value
==-1 && (e
->op
== "&"))))
4604 (right
&& ((right
->value
== 0 && (e
->op
== "+" || e
->op
== "-" ||
4605 e
->op
== "|" || e
->op
== "^")) ||
4606 (right
->value
== 1 && (e
->op
== "*" || e
->op
== "/")) ||
4607 (right
->value
==-1 && (e
->op
== "&")) ||
4608 (right
->value
<= 0 && (e
->op
== ">>" || e
->op
== "<<")))))
4610 if (session
.verbose
>2)
4611 clog
<< _("Collapsing constant-identity binary operator ") << *e
->tok
<< endl
;
4614 // we'll pass on type=pe_long inference to the expression
4615 expression
* other
= left
? e
->right
: e
->left
;
4616 if (other
->type
== pe_unknown
)
4617 other
->type
= pe_long
;
4618 else if (other
->type
!= pe_long
)
4620 // this mismatch was not caught in the initial type resolution pass,
4621 // generate a mismatch (left doesn't match right) error
4622 typeresolution_info
ti(session
);
4623 ti
.assert_resolvability
= true; // need this to get it throw errors
4624 ti
.mismatch_complexity
= 1; // also needed to throw errors
4638 if (session
.verbose
>2)
4639 clog
<< _F("Collapsing constant-%" PRIi64
" binary operator %s",
4640 value
, lex_cast(*e
->tok
).c_str()) << endl
;
4643 literal_number
* n
= new literal_number(value
);
4649 const_folder::visit_unary_expression (unary_expression
* e
)
4651 literal_number
* operand
= get_number (e
->operand
);
4656 if (session
.verbose
>2)
4657 clog
<< _("Collapsing constant unary ") << *e
->tok
<< endl
;
4660 literal_number
* n
= new literal_number (*operand
);
4664 else if (e
->op
== "-")
4665 n
->value
= -n
->value
;
4666 else if (e
->op
== "!")
4667 n
->value
= !n
->value
;
4668 else if (e
->op
== "~")
4669 n
->value
= ~n
->value
;
4671 throw SEMANTIC_ERROR (_("unsupported unary operator ") + (string
)e
->op
);
4677 const_folder::visit_logical_or_expr (logical_or_expr
* e
)
4680 literal_number
* left
= get_number (e
->left
);
4681 literal_number
* right
= get_number (e
->right
);
4684 value
= left
->value
|| right
->value
;
4686 else if ((left
&& left
->value
) || (right
&& right
->value
))
4688 // If the const is on the left, we get to short-circuit the right
4689 // immediately. Otherwise, we can only eliminate the LHS if it's pure.
4692 varuse_collecting_visitor
vu(session
);
4693 e
->left
->visit(&vu
);
4694 if (!vu
.side_effect_free())
4704 // We might also get rid of useless "0||x" and "x||0", except it does
4705 // normalize x to 0 or 1. We could change it to "!!x", but it's not clear
4706 // that this would gain us much.
4714 if (session
.verbose
>2)
4715 clog
<< _("Collapsing constant logical-OR ") << *e
->tok
<< endl
;
4718 literal_number
* n
= new literal_number(value
);
4724 const_folder::visit_logical_and_expr (logical_and_expr
* e
)
4727 literal_number
* left
= get_number (e
->left
);
4728 literal_number
* right
= get_number (e
->right
);
4731 value
= left
->value
&& right
->value
;
4733 else if ((left
&& !left
->value
) || (right
&& !right
->value
))
4735 // If the const is on the left, we get to short-circuit the right
4736 // immediately. Otherwise, we can only eliminate the LHS if it's pure.
4739 varuse_collecting_visitor
vu(session
);
4740 e
->left
->visit(&vu
);
4741 if (!vu
.side_effect_free())
4751 // We might also get rid of useless "1&&x" and "x&&1", except it does
4752 // normalize x to 0 or 1. We could change it to "!!x", but it's not clear
4753 // that this would gain us much.
4761 if (session
.verbose
>2)
4762 clog
<< _("Collapsing constant logical-AND ") << *e
->tok
<< endl
;
4765 literal_number
* n
= new literal_number(value
);
4771 const_folder::visit_compound_expression (compound_expression
* e
)
4773 replace(e
->left
, true);
4774 replace(e
->right
, false);
4776 // If the LHS is pure, we can eliminate it.
4777 // ??? This is unlikely, given how these are created in loc2stap.cxx.
4780 varuse_collecting_visitor
vu(session
);
4781 e
->left
->visit(&vu
);
4782 if (!vu
.side_effect_free())
4789 if (session
.verbose
> 2)
4790 clog
<< _("Collapsing compound expression") << *e
->tok
<< endl
;
4796 const_folder::visit_comparison (comparison
* e
)
4800 literal_number
*left_num
, *right_num
;
4801 literal_string
*left_str
, *right_str
;
4802 get_literal(e
->left
, left_num
, left_str
);
4803 get_literal(e
->right
, right_num
, right_str
);
4805 if (left_str
&& right_str
)
4806 comp
= left_str
->value
.compare(right_str
->value
);
4808 else if (left_num
&& right_num
)
4809 comp
= left_num
->value
< right_num
->value
? -1 :
4810 left_num
->value
> right_num
->value
? 1 : 0;
4812 else if ((left_num
&& ((left_num
->value
== LLONG_MIN
&&
4813 (e
->op
== "<=" || e
->op
== ">")) ||
4814 (left_num
->value
== LLONG_MAX
&&
4815 (e
->op
== ">=" || e
->op
== "<"))))
4817 (right_num
&& ((right_num
->value
== LLONG_MIN
&&
4818 (e
->op
== ">=" || e
->op
== "<")) ||
4819 (right_num
->value
== LLONG_MAX
&&
4820 (e
->op
== "<=" || e
->op
== ">")))))
4822 expression
* other
= left_num
? e
->right
: e
->left
;
4823 varuse_collecting_visitor
vu(session
);
4825 if (!vu
.side_effect_free())
4829 if (session
.verbose
>2)
4830 clog
<< _("Collapsing constant-boundary comparison ") << *e
->tok
<< endl
;
4833 // ops <= and >= are true, < and > are false
4834 literal_number
* n
= new literal_number( e
->op
.length() == 2 );
4847 if (session
.verbose
>2)
4848 clog
<< _("Collapsing constant comparison ") << *e
->tok
<< endl
;
4854 else if (e
->op
== "!=")
4856 else if (e
->op
== "<")
4858 else if (e
->op
== ">")
4860 else if (e
->op
== "<=")
4862 else if (e
->op
== ">=")
4865 throw SEMANTIC_ERROR (_("unsupported comparison operator ") + (string
)e
->op
);
4867 literal_number
* n
= new literal_number(value
);
4873 const_folder::visit_concatenation (concatenation
* e
)
4875 literal_string
* left
= get_string (e
->left
);
4876 literal_string
* right
= get_string (e
->right
);
4880 if (session
.verbose
>2)
4881 clog
<< _("Collapsing constant concatenation ") << *e
->tok
<< endl
;
4884 literal_string
* n
= new literal_string (*left
);
4886 n
->value
= (string
)n
->value
+ (string
)right
->value
;
4889 else if ((left
&& left
->value
.empty()) ||
4890 (right
&& right
->value
.empty()))
4892 if (session
.verbose
>2)
4893 clog
<< _("Collapsing identity concatenation ") << *e
->tok
<< endl
;
4895 provide(left
? e
->right
: e
->left
);
4902 const_folder::visit_ternary_expression (ternary_expression
* e
)
4904 literal_number
* cond
= get_number (e
->cond
);
4907 replace (e
->truevalue
);
4908 replace (e
->falsevalue
);
4913 if (session
.verbose
>2)
4914 clog
<< _F("Collapsing constant-%" PRIi64
" ternary %s",
4915 cond
->value
, lex_cast(*e
->tok
).c_str()) << endl
;
4918 expression
* n
= cond
->value
? e
->truevalue
: e
->falsevalue
;
4924 const_folder::visit_defined_op (defined_op
* e
)
4926 // If a @defined makes it this far, then it was not resolved by
4927 // previous efforts. We could assume that therefore it is a big fat
4928 // zero, but for the @defined(autocast) case PR18079, this just
4929 // means that we didn't know yet.
4931 bool collapse_this
= false;
4933 /* PR20672: not true; we run a const_folder iteratively during
4934 initial probe body variable-expansion, when other @defined()s may
4935 be as-yet-unprocessed. We can't presume to map them to zero.
4937 // We do know that plain target_symbols aren't going anywhere though.
4938 if (get_target_symbol (e->operand))
4940 if (session.verbose>2)
4941 clog << _("Collapsing target_symbol @defined check ") << *e->tok << endl;
4942 collapse_this = true;
4946 if (collapse_defines_p
&& relaxed_p
)
4948 if (session
.verbose
>2)
4949 clog
<< _("Collapsing untouched @defined check ") << *e
->tok
<< endl
;
4951 // If we got to an expression with a known type, call it defined.
4952 if (e
->operand
->type
!= pe_unknown
)
4954 collapse_this
= true;
4959 // Don't be greedy... we'll only collapse one at a time so type
4960 // resolution can have another go at it.
4962 literal_number
* n
= new literal_number (value
);
4968 if (session
.verbose
>2)
4969 clog
<< _("Preserving unresolved @defined check ") << *e
->tok
<< endl
;
4975 const_folder::get_target_symbol(expression
*& e
)
4978 return (e
== last_target_symbol
) ? last_target_symbol
: NULL
;
4982 const_folder::visit_target_symbol (target_symbol
* e
)
4984 if (collapse_defines_p
&& session
.skip_badvars
)
4986 // Upon user request for ignoring context, the symbol is replaced
4987 // with a literal 0 and a warning message displayed
4988 // ... but don't do this during early runs of the const_folder, only
4989 // during the final (collapse_defines_p) one. (Otherwise, during
4990 // a dwarf_var "@defined($foo) ? $foo : 0", the inner $foo could
4991 // get premature mapping to 0.
4993 // XXX this ignores possible side-effects, e.g. in array indexes
4994 literal_number
* ln_zero
= new literal_number (0);
4995 ln_zero
->tok
= e
->tok
;
4997 session
.print_warning (_("Bad $context variable being substituted with literal 0"),
5003 update_visitor::visit_target_symbol (e
);
5004 last_target_symbol
= e
;
5008 static int initial_typeres_pass(systemtap_session
& s
);
5009 static int semantic_pass_const_fold (systemtap_session
& s
, bool& relaxed_p
)
5011 // attempt an initial type resolution pass to see if there are any type
5012 // mismatches before we starting whisking away vars that get switched out
5015 // return if the initial type resolution pass reported errors (type mismatches)
5016 int rc
= initial_typeres_pass(s
);
5023 // Let's simplify statements with constant values.
5024 const_folder
cf (s
, relaxed_p
, true /* collapse remaining @defined()->0 now */ );
5025 // This instance may be reused for multiple probe/function body trims.
5027 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
5028 cf
.replace (s
.probes
[i
]->body
);
5029 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
5030 it
!= s
.functions
.end(); it
++)
5031 cf
.replace (it
->second
->body
);
5036 struct dead_control_remover
: public traversing_visitor
5038 systemtap_session
& session
;
5042 dead_control_remover(systemtap_session
& s
, bool& r
):
5043 session(s
), relaxed_p(r
), control(NULL
) {}
5045 void visit_block (block
*b
);
5047 // When a block contains any of these, the following statements are dead.
5048 void visit_return_statement (return_statement
* s
) { control
= s
; }
5049 void visit_next_statement (next_statement
* s
) { control
= s
; }
5050 void visit_break_statement (break_statement
* s
) { control
= s
; }
5051 void visit_continue_statement (continue_statement
* s
) { control
= s
; }
5055 void dead_control_remover::visit_block (block
* b
)
5057 vector
<statement
*>& vs
= b
->statements
;
5058 if (vs
.size() == 0) /* else (size_t) size()-1 => very big */
5060 for (size_t i
= 0; i
< vs
.size() - 1; ++i
)
5062 vs
[i
]->visit (this);
5063 if (vs
[i
] == control
)
5065 session
.print_warning(_("statement will never be reached"),
5067 vs
.erase(vs
.begin() + i
+ 1, vs
.end());
5075 static void semantic_pass_dead_control (systemtap_session
& s
, bool& relaxed_p
)
5077 // Let's remove code that follow unconditional control statements
5079 dead_control_remover
dc (s
, relaxed_p
);
5081 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
5082 s
.probes
[i
]->body
->visit(&dc
);
5084 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
5085 it
!= s
.functions
.end(); it
++)
5086 it
->second
->body
->visit(&dc
);
5090 // Looks for next statements in function declarations and marks
5092 struct function_next_check
: public traversing_visitor
5094 functiondecl
* current_function
;
5096 function_next_check()
5097 : current_function(0) { }
5099 void visit_next_statement(next_statement
*)
5101 current_function
->has_next
= true;
5104 void visit_embeddedcode(embeddedcode
* s
)
5106 if (s
->tagged_p("STAP_NEXT;"))
5107 current_function
->has_next
= true;
5111 struct dead_overload_remover
: public traversing_visitor
5113 systemtap_session
& s
;
5116 dead_overload_remover(systemtap_session
& sess
,
5118 : s(sess
), relaxed_p(r
) { }
5120 void visit_functioncall(functioncall
* e
);
5123 void dead_overload_remover::visit_functioncall(functioncall
*e
)
5125 unsigned reachable
= 1;
5126 bool chained
= true;
5128 for (unsigned fd
= 0; fd
< e
->referents
.size(); fd
++)
5130 functiondecl
* r
= e
->referents
[fd
];
5132 // Note that this is not a sound inference but it suffices for most
5133 // cases. It may be the case that there is a 'next' statement in the
5134 // function that will never be executed by the control flow.
5135 // We simply use the presence of a 'next' statement as an indicator
5136 // of a potential fall through. Once a function can't be 'nexted' the
5137 // remaining functions are unreachable.
5138 if (chained
&& r
->has_next
)
5144 if (reachable
< e
->referents
.size())
5146 for (unsigned fd
= reachable
; fd
< e
->referents
.size(); fd
++)
5148 functiondecl
* r
= e
->referents
[fd
];
5149 s
.print_warning(_("instance of overloaded function will "
5150 "never be reached"), r
->tok
);
5152 e
->referents
.erase(e
->referents
.begin()+reachable
, e
->referents
.end());
5157 static void semantic_pass_overload(systemtap_session
& s
, bool& relaxed_p
)
5159 set
<functiondecl
*> function_next
;
5160 function_next_check fnc
;
5162 for (auto it
= s
.functions
.begin(); it
!= s
.functions
.end(); ++it
)
5164 functiondecl
* fn
= it
->second
;
5165 fnc
.current_function
= fn
;
5166 fn
->body
->visit(&fnc
);
5169 for (auto it
= s
.probes
.begin(); it
!= s
.probes
.end(); ++it
)
5171 dead_overload_remover
ovr(s
, relaxed_p
);
5172 (*it
)->body
->visit(&ovr
);
5175 for (auto it
= s
.functions
.begin(); it
!= s
.functions
.end(); ++it
)
5177 dead_overload_remover
ovr(s
, relaxed_p
);
5178 it
->second
->body
->visit(&ovr
);
5183 struct duplicate_function_remover
: public functioncall_traversing_visitor
5185 systemtap_session
& s
;
5186 map
<functiondecl
*, functiondecl
*>& duplicate_function_map
;
5188 duplicate_function_remover(systemtap_session
& sess
,
5189 map
<functiondecl
*, functiondecl
*>&dfm
):
5190 s(sess
), duplicate_function_map(dfm
) {};
5192 void visit_functioncall (functioncall
* e
);
5196 duplicate_function_remover::visit_functioncall (functioncall
*e
)
5198 functioncall_traversing_visitor::visit_functioncall (e
);
5200 // If any of the current function call references points to a function that
5201 // is a duplicate, replace it.
5202 for (unsigned i
= 0; i
< e
->referents
.size(); i
++)
5204 functiondecl
* referent
= e
->referents
[i
];
5205 if (duplicate_function_map
.count(referent
) != 0)
5208 clog
<< _F("Changing %s reference to %s reference\n",
5209 referent
->unmangled_name
.to_string().c_str(),
5210 duplicate_function_map
[referent
]->unmangled_name
.to_string().c_str());
5211 e
->tok
= duplicate_function_map
[referent
]->tok
;
5212 e
->function
= duplicate_function_map
[referent
]->name
;
5213 e
->referents
[i
] = duplicate_function_map
[referent
];
5219 get_functionsig (functiondecl
* f
)
5223 // Get the "name:args body" of the function in s. We have to
5224 // include the args since the function 'x1(a, b)' is different than
5225 // the function 'x2(b, a)' even if the bodies of the two functions
5226 // are exactly the same.
5230 // printsig puts f->name + ':' on the front. Remove this
5231 // (otherwise, functions would never compare equal).
5232 string str
= s
.str().erase(0, f
->unmangled_name
.size() + 1);
5234 // Return the function signature.
5238 void semantic_pass_opt6 (systemtap_session
& s
, bool& relaxed_p
)
5240 // Walk through all the functions, looking for duplicates.
5241 map
<string
, functiondecl
*> functionsig_map
;
5242 map
<functiondecl
*, functiondecl
*> duplicate_function_map
;
5245 vector
<functiondecl
*> newly_zapped_functions
;
5246 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
5248 functiondecl
*fd
= it
->second
;
5249 string functionsig
= get_functionsig(fd
);
5251 if (functionsig_map
.count(functionsig
) == 0)
5253 // This function is unique. Remember it.
5254 functionsig_map
[functionsig
] = fd
;
5258 // This function is a duplicate.
5259 duplicate_function_map
[fd
] = functionsig_map
[functionsig
];
5260 newly_zapped_functions
.push_back (fd
);
5264 for (unsigned i
=0; i
<newly_zapped_functions
.size(); i
++)
5266 map
<string
,functiondecl
*>::iterator where
= s
.functions
.find (newly_zapped_functions
[i
]->name
);
5267 assert (where
!= s
.functions
.end());
5268 s
.functions
.erase (where
);
5272 // If we have duplicate functions, traverse down the tree, replacing
5273 // the appropriate function calls.
5274 // duplicate_function_remover::visit_functioncall() handles the
5275 // details of replacing the function calls.
5276 if (duplicate_function_map
.size() != 0)
5278 duplicate_function_remover
dfr (s
, duplicate_function_map
);
5280 for (unsigned i
=0; i
< s
.probes
.size(); i
++)
5281 s
.probes
[i
]->body
->visit(&dfr
);
5285 struct stable_analysis
: public nop_visitor
5288 stable_analysis(): stable(false) {};
5290 void visit_embeddedcode (embeddedcode
* s
);
5293 void stable_analysis::visit_embeddedcode (embeddedcode
* s
)
5295 if (s
->tagged_p("/* stable */"))
5297 if (stable
&& !s
->tagged_p("/* pure */"))
5298 throw SEMANTIC_ERROR(_("stable function must also be /* pure */"),
5302 // Examines entire subtree for any stable functioncalls.
5303 struct stable_finder
: public traversing_visitor
5306 set
<string
>& stable_fcs
;
5307 stable_finder(set
<string
>&s
): stable(false), stable_fcs(s
) {};
5308 void visit_functioncall (functioncall
* e
);
5311 void stable_finder::visit_functioncall (functioncall
* e
)
5313 if (stable_fcs
.find(e
->function
) != stable_fcs
.end())
5315 traversing_visitor::visit_functioncall(e
);
5318 // Examines current level of block for stable functioncalls.
5319 // Does not descend into sublevels.
5320 struct level_check
: public traversing_visitor
5323 set
<string
>& stable_fcs
;
5324 level_check(set
<string
>& s
): stable(false), stable_fcs(s
) {};
5326 void visit_block (block
* s
);
5327 void visit_try_block (try_block
*s
);
5328 void visit_if_statement (if_statement
* s
);
5329 void visit_for_loop (for_loop
* s
);
5330 void visit_foreach_loop (foreach_loop
* s
);
5331 void visit_functioncall (functioncall
* s
);
5334 void level_check::visit_block (block
*)
5338 void level_check::visit_try_block (try_block
* s
)
5340 if (s
->catch_error_var
)
5341 s
->catch_error_var
->visit(this);
5344 void level_check::visit_if_statement (if_statement
* s
)
5346 s
->condition
->visit(this);
5349 void level_check::visit_for_loop (for_loop
* s
)
5351 if (s
->init
) s
->init
->visit(this);
5352 s
->cond
->visit(this);
5353 if (s
->incr
) s
->incr
->visit(this);
5356 void level_check::visit_foreach_loop (foreach_loop
* s
)
5358 s
->base
->visit(this);
5360 for (unsigned i
=0; i
<s
->indexes
.size(); i
++)
5361 s
->indexes
[i
]->visit(this);
5364 s
->value
->visit(this);
5367 s
->limit
->visit(this);
5370 void level_check::visit_functioncall (functioncall
* e
)
5372 if (stable_fcs
.find(e
->function
) != stable_fcs
.end())
5374 traversing_visitor::visit_functioncall(e
);
5377 struct stable_functioncall_visitor
: public update_visitor
5379 systemtap_session
& session
;
5380 functiondecl
* current_function
;
5381 derived_probe
* current_probe
;
5382 set
<string
>& stable_fcs
;
5383 set
<string
> scope_vars
;
5384 map
<string
,vardecl
*> new_vars
;
5385 vector
<pair
<expr_statement
*,block
*> > new_stmts
;
5386 unsigned loop_depth
;
5389 stable_functioncall_visitor(systemtap_session
& s
, set
<string
>& sfc
):
5390 update_visitor(s
.verbose
),
5391 session(s
), current_function(0), current_probe(0), stable_fcs(sfc
),
5392 loop_depth(0), top_scope(0), curr_scope(0) {};
5394 statement
* convert_stmt(statement
* s
);
5395 void visit_block (block
* s
);
5396 void visit_try_block (try_block
* s
);
5397 void visit_if_statement (if_statement
* s
);
5398 void visit_for_loop (for_loop
* s
);
5399 void visit_foreach_loop (foreach_loop
* s
);
5400 void visit_functioncall (functioncall
* e
);
5403 statement
* stable_functioncall_visitor::convert_stmt (statement
* s
)
5405 if (top_scope
== 0 &&
5406 (dynamic_cast<for_loop
*>(s
) || dynamic_cast<foreach_loop
*>(s
)))
5408 stable_finder
sf(stable_fcs
);
5412 block
* b
= new block
;
5414 b
->statements
.push_back(s
);
5418 else if (top_scope
== 0 && !dynamic_cast<block
*>(s
))
5420 level_check
lc(stable_fcs
);
5424 block
* b
= new block
;
5426 b
->statements
.push_back(s
);
5434 void stable_functioncall_visitor::visit_block (block
* s
)
5436 block
* prev_top_scope
= top_scope
;
5437 block
* prev_scope
= curr_scope
;
5438 if (loop_depth
== 0)
5441 set
<string
> current_vars
= scope_vars
;
5443 update_visitor::visit_block(s
);
5445 if (loop_depth
== 0)
5446 top_scope
= prev_top_scope
;
5447 curr_scope
= prev_scope
;
5448 scope_vars
= current_vars
;
5451 void stable_functioncall_visitor::visit_try_block (try_block
* s
)
5454 s
->try_block
= convert_stmt(s
->try_block
);
5455 replace(s
->try_block
);
5456 replace(s
->catch_error_var
);
5458 s
->catch_block
= convert_stmt(s
->catch_block
);
5459 replace(s
->catch_block
);
5463 void stable_functioncall_visitor::visit_if_statement (if_statement
* s
)
5465 block
* prev_top_scope
= top_scope
;
5467 if (loop_depth
== 0)
5469 replace(s
->condition
);
5470 s
->thenblock
= convert_stmt(s
->thenblock
);
5471 replace(s
->thenblock
);
5472 if (loop_depth
== 0)
5475 s
->elseblock
= convert_stmt(s
->elseblock
);
5476 replace(s
->elseblock
);
5479 top_scope
= prev_top_scope
;
5482 void stable_functioncall_visitor::visit_for_loop (for_loop
* s
)
5488 s
->block
= convert_stmt(s
->block
);
5494 void stable_functioncall_visitor::visit_foreach_loop (foreach_loop
* s
)
5496 for (unsigned i
= 0; i
< s
->indexes
.size(); ++i
)
5497 replace(s
->indexes
[i
]);
5502 s
->block
= convert_stmt(s
->block
);
5508 void stable_functioncall_visitor::visit_functioncall (functioncall
* e
)
5510 for (unsigned i
= 0; i
< e
->args
.size(); ++i
)
5511 replace (e
->args
[i
]);
5513 if (stable_fcs
.find(e
->function
) != stable_fcs
.end())
5515 string
name("__stable_");
5516 name
.append(e
->function
).append("_value");
5518 // Variable potentially not in scope since it is in a sibling block
5519 if (scope_vars
.find(e
->function
) == scope_vars
.end())
5521 if (new_vars
.find(e
->function
) == new_vars
.end())
5523 // New variable declaration to store result of function call
5524 vardecl
* v
= new vardecl
;
5525 v
->unmangled_name
= v
->name
= name
;
5527 v
->set_arity(0, e
->tok
);
5529 if (current_function
)
5530 current_function
->locals
.push_back(v
);
5532 current_probe
->locals
.push_back(v
);
5533 new_vars
[e
->function
] = v
;
5536 symbol
* sym
= new symbol
;
5539 sym
->referent
= new_vars
[e
->function
];
5540 sym
->type
= e
->type
;
5542 functioncall
* fc
= new functioncall
;
5544 fc
->function
= e
->function
;
5545 fc
->referents
= e
->referents
;
5548 assignment
* a
= new assignment
;
5555 expr_statement
* es
= new expr_statement
;
5559 // Store location of the block to put new declaration.
5560 if (loop_depth
!= 0)
5563 new_stmts
.push_back(make_pair(es
,top_scope
));
5568 new_stmts
.push_back(make_pair(es
,curr_scope
));
5571 scope_vars
.insert(e
->function
);
5577 symbol
* sym
= new symbol
;
5580 sym
->referent
= new_vars
[e
->function
];
5581 sym
->type
= e
->type
;
5590 // Cache stable embedded-c functioncall results and replace
5591 // all calls with same name using that value to reduce duplicate
5592 // functioncall overhead. Functioncalls are pulled out of any
5593 // top-level loops and put into if/try blocks.
5594 void semantic_pass_opt7(systemtap_session
& s
)
5596 set
<string
> stable_fcs
;
5597 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
5598 it
!= s
.functions
.end(); ++it
)
5600 functiondecl
* fn
= (*it
).second
;
5602 fn
->body
->visit(&sa
);
5603 if (sa
.stable
&& fn
->formal_args
.size() == 0)
5604 stable_fcs
.insert(fn
->name
);
5607 for (vector
<derived_probe
*>::iterator it
= s
.probes
.begin();
5608 it
!= s
.probes
.end(); ++it
)
5610 stable_functioncall_visitor
t(s
, stable_fcs
);
5611 t
.current_probe
= *it
;
5612 (*it
)->body
= t
.convert_stmt((*it
)->body
);
5613 t
.replace((*it
)->body
);
5615 for (vector
<pair
<expr_statement
*,block
*> >::iterator st
= t
.new_stmts
.begin();
5616 st
!= t
.new_stmts
.end(); ++st
)
5617 st
->second
->statements
.insert(st
->second
->statements
.begin(), st
->first
);
5620 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
5621 it
!= s
.functions
.end(); ++it
)
5623 functiondecl
* fn
= (*it
).second
;
5624 stable_functioncall_visitor
t(s
, stable_fcs
);
5625 t
.current_function
= fn
;
5626 fn
->body
= t
.convert_stmt(fn
->body
);
5627 t
.replace(fn
->body
);
5629 for (vector
<pair
<expr_statement
*,block
*> >::iterator st
= t
.new_stmts
.begin();
5630 st
!= t
.new_stmts
.end(); ++st
)
5631 st
->second
->statements
.insert(st
->second
->statements
.begin(), st
->first
);
5636 semantic_pass_optimize1 (systemtap_session
& s
)
5638 // In this pass, we attempt to rewrite probe/function bodies to
5639 // eliminate some blatantly unnecessary code. This is run before
5640 // type inference, but after symbol resolution and derived_probe
5641 // creation. We run an outer "relaxation" loop that repeats the
5642 // optimizations until none of them find anything to remove.
5646 bool relaxed_p
= false;
5647 unsigned iterations
= 0;
5650 // Save the old value of suppress_warnings, as we will be changing
5652 save_and_restore
<bool> suppress_warnings(& s
.suppress_warnings
);
5654 assert_no_interrupts();
5656 relaxed_p
= true; // until proven otherwise
5658 // If the verbosity is high enough, always print warnings (overrides -w),
5659 // or if not, always suppress warnings for every itteration after the first.
5661 s
.suppress_warnings
= false;
5662 else if (iterations
> 0)
5663 s
.suppress_warnings
= true;
5667 semantic_pass_opt1 (s
, relaxed_p
);
5668 semantic_pass_opt2 (s
, relaxed_p
, iterations
); // produce some warnings only on iteration=0
5669 semantic_pass_opt3 (s
, relaxed_p
);
5670 semantic_pass_opt4 (s
, relaxed_p
);
5671 semantic_pass_opt5 (s
, relaxed_p
);
5674 // For listing mode, we need const-folding regardless of optimization so
5675 // that @defined expressions can be properly resolved. PR11360
5676 // We also want it in case variables are used in if/case expressions,
5677 // so enable always. PR11366
5678 // rc is incremented if there is an error that got reported.
5679 rc
+= semantic_pass_const_fold (s
, relaxed_p
);
5682 semantic_pass_dead_control (s
, relaxed_p
);
5685 semantic_pass_overload (s
, relaxed_p
);
5690 // We will now remove probes that have empty handlers and join the remaining probes
5691 // with their groups. Do not elide probes when the unoptimziation flag is set.
5693 vector
<derived_probe
*> non_empty_probes
;
5695 for (unsigned i
= 0; i
< s
.probes
.size(); i
++)
5697 derived_probe
* p
= s
.probes
[i
];
5699 if (s
.unoptimized
|| s
.dump_mode
)
5701 else if (s
.empty_probes
.find(p
) == s
.empty_probes
.end())
5703 non_empty_probes
.push_back(p
);
5706 else if (!s
.timing
&& // PR10070
5707 !(p
->base
->tok
->location
.file
->synthetic
)) // don't warn for synthetic probes
5708 s
.print_warning(_F("Probe '%s' has been elided",
5709 ((string
) p
->locations
[0]->components
[0]->functor
).c_str()), p
->tok
);
5712 if (!s
.unoptimized
&& !s
.dump_mode
)
5713 s
.probes
= non_empty_probes
;
5720 semantic_pass_optimize2 (systemtap_session
& s
)
5722 // This is run after type inference. We run an outer "relaxation"
5723 // loop that repeats the optimizations until none of them find
5724 // anything to remove.
5728 // Save the old value of suppress_warnings, as we will be changing
5730 save_and_restore
<bool> suppress_warnings(& s
.suppress_warnings
);
5732 bool relaxed_p
= false;
5733 unsigned iterations
= 0;
5736 assert_no_interrupts();
5737 relaxed_p
= true; // until proven otherwise
5739 // If the verbosity is high enough, always print warnings (overrides -w),
5740 // or if not, always suppress warnings for every itteration after the first.
5742 s
.suppress_warnings
= false;
5743 else if (iterations
> 0)
5744 s
.suppress_warnings
= true;
5747 semantic_pass_opt6 (s
, relaxed_p
);
5753 semantic_pass_opt7(s
);
5760 // ------------------------------------------------------------------------
5763 struct autocast_expanding_visitor
: public var_expanding_visitor
5765 typeresolution_info
& ti
;
5766 autocast_expanding_visitor (systemtap_session
& s
, typeresolution_info
& ti
):
5767 var_expanding_visitor(s
), ti(ti
) {}
5769 void resolve_functioncall (functioncall
* fc
)
5771 // This is a very limited version of semantic_pass_symbols, but
5772 // we're late in the game at this point (after basic symbol
5773 // resolution already took place). We won't get a chance to
5774 // optimize, but for now the only functions we expect are
5775 // kernel/user_string from pretty-printing, which don't need
5778 systemtap_session
& s
= ti
.session
;
5779 size_t nfiles
= s
.files
.size();
5781 symresolution_info
sym (s
);
5782 sym
.current_function
= ti
.current_function
;
5783 sym
.current_probe
= ti
.current_probe
;
5786 // NB: synthetic functions get tacked onto the origin file, so we won't
5787 // see them growing s.files[]. Traverse it directly.
5788 for (unsigned i
= 0; i
< fc
->referents
.size(); i
++)
5790 functiondecl
* fd
= fc
->referents
[i
];
5791 sym
.current_function
= fd
;
5792 sym
.current_probe
= 0;
5793 fd
->body
->visit (&sym
);
5796 while (nfiles
< s
.files
.size())
5798 stapfile
* dome
= s
.files
[nfiles
++];
5799 for (size_t i
= 0; i
< dome
->functions
.size(); ++i
)
5801 functiondecl
* fd
= dome
->functions
[i
];
5802 sym
.current_function
= fd
;
5803 sym
.current_probe
= 0;
5804 fd
->body
->visit (&sym
);
5805 // NB: not adding to s.functions just yet...
5809 // Add only the direct functions we need.
5810 functioncall_traversing_visitor ftv
;
5812 for (set
<functiondecl
*>::iterator it
= ftv
.seen
.begin();
5813 it
!= ftv
.seen
.end(); ++it
)
5815 functiondecl
* fd
= *it
;
5816 pair
<map
<string
,functiondecl
*>::iterator
,bool> inserted
=
5817 s
.functions
.insert (make_pair (fd
->name
, fd
));
5818 if (!inserted
.second
&& inserted
.first
->second
!= fd
)
5819 throw SEMANTIC_ERROR
5820 (_F("resolved function '%s' conflicts with an existing function",
5821 fd
->unmangled_name
.to_string().c_str()), fc
->tok
);
5825 void visit_autocast_op (autocast_op
* e
)
5827 const bool lvalue
= is_active_lvalue (e
);
5828 const exp_type_ptr
& details
= e
->operand
->type_details
;
5829 if (details
&& !e
->saved_conversion_error
)
5831 functioncall
* fc
= details
->expand (e
, lvalue
);
5834 ti
.num_newly_resolved
++;
5836 resolve_functioncall (fc
);
5837 // NB: at this stage, the functioncall object has one
5838 // argument too few if we're in lvalue context. It will
5839 // be filled in only later (as the
5840 // var_expanding_visitor::visit_assignment bit rolls
5841 // back up). But nevertheless we must resolve the fc,
5842 // otherwise, symresolution_info::visit_functioncall will
5843 // throw a mismatched-arity error. (semok/autocast08.stp)
5846 provide_lvalue_call (fc
);
5852 var_expanding_visitor::visit_autocast_op (e
);
5857 struct initial_typeresolution_info
: public typeresolution_info
5859 initial_typeresolution_info (systemtap_session
& s
): typeresolution_info(s
)
5862 // these expressions are not supposed to make its way to the typeresolution
5863 // pass. they probably get substituted/replaced, but since this is an initial pass
5864 // and not all substitutions are done, replace the functions that throw errors.
5865 void visit_target_symbol (target_symbol
*) {}
5866 void visit_atvar_op (atvar_op
*) {}
5867 void visit_defined_op (defined_op
*) {}
5868 void visit_entry_op (entry_op
*) {}
5869 void visit_cast_op (cast_op
*) {}
5872 static int initial_typeres_pass(systemtap_session
& s
)
5874 // minimal type resolution based off of semantic_pass_types(), without
5875 // checking for complete type resolutions or autocast expanding
5876 initial_typeresolution_info
ti(s
);
5878 ti
.assert_resolvability
= false;
5881 assert_no_interrupts();
5883 ti
.num_newly_resolved
= 0;
5884 ti
.num_still_unresolved
= 0;
5885 ti
.num_available_autocasts
= 0;
5887 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
5888 it
!= s
.functions
.end(); it
++)
5890 assert_no_interrupts();
5892 functiondecl
* fd
= it
->second
;
5893 ti
.current_probe
= 0;
5894 ti
.current_function
= fd
;
5896 fd
->body
->visit (& ti
);
5899 for (unsigned j
=0; j
<s
.probes
.size(); j
++)
5901 assert_no_interrupts();
5903 derived_probe
* pn
= s
.probes
[j
];
5904 ti
.current_function
= 0;
5905 ti
.current_probe
= pn
;
5907 pn
->body
->visit (& ti
);
5909 probe_point
* pp
= pn
->sole_location();
5912 ti
.current_function
= 0;
5913 ti
.current_probe
= 0;
5914 ti
.t
= pe_long
; // NB: expected type
5915 pp
->condition
->visit (& ti
);
5918 if (ti
.num_newly_resolved
== 0) // converged
5920 // take into account that if there are mismatches, we'd want to know
5921 // about them incase they get whisked away, later in this process
5922 if (!ti
.assert_resolvability
&& ti
.mismatch_complexity
> 0) // found a mismatch!!
5924 ti
.assert_resolvability
= true; // report errors
5926 ti
.mismatch_complexity
= 1; // print out mismatched but not unresolved type mismatches
5932 ti
.mismatch_complexity
= 0;
5935 return s
.num_errors();
5939 semantic_pass_types (systemtap_session
& s
)
5943 // next pass: type inference
5944 unsigned iterations
= 0;
5945 typeresolution_info
ti (s
);
5947 ti
.assert_resolvability
= false;
5950 assert_no_interrupts();
5953 ti
.num_newly_resolved
= 0;
5954 ti
.num_still_unresolved
= 0;
5955 ti
.num_available_autocasts
= 0;
5957 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
5958 it
!= s
.functions
.end(); it
++)
5961 assert_no_interrupts();
5963 functiondecl
* fd
= it
->second
;
5964 ti
.current_probe
= 0;
5965 ti
.current_function
= fd
;
5968 fd
->body
->visit (& ti
);
5969 // NB: we don't have to assert a known type for
5970 // functions here, to permit a "void" function.
5971 // The translator phase will omit the "retvalue".
5973 // if (fd->type == pe_unknown)
5974 // ti.unresolved (fd->tok);
5975 for (unsigned i
=0; i
< fd
->locals
.size(); ++i
)
5976 ti
.check_local (fd
->locals
[i
]);
5978 // Check and run the autocast expanding visitor.
5979 if (ti
.num_available_autocasts
> 0)
5981 autocast_expanding_visitor
aev (s
, ti
);
5982 aev
.replace (fd
->body
);
5984 // PR18079, rerun the const-folder / dead-block-remover
5985 // if autocast evaluation enabled a @defined()
5986 if (! aev
.relaxed())
5988 bool relaxed_p
= true;
5989 const_folder
cf (s
, relaxed_p
);
5990 cf
.replace (fd
->body
);
5991 if (! s
.unoptimized
)
5993 dead_control_remover
dc (s
, relaxed_p
);
5994 fd
->body
->visit (&dc
);
5996 (void) relaxed_p
; // we judge success later by num_still_unresolved, not this flag
5999 ti
.num_available_autocasts
= 0;
6002 catch (const semantic_error
& e
)
6004 throw SEMANTIC_ERROR(_F("while processing function %s",
6005 it
->second
->unmangled_name
.to_string().c_str())).set_chain(e
);
6008 for (unsigned j
=0; j
<s
.probes
.size(); j
++)
6011 assert_no_interrupts();
6013 derived_probe
* pn
= s
.probes
[j
];
6014 ti
.current_function
= 0;
6015 ti
.current_probe
= pn
;
6018 pn
->body
->visit (& ti
);
6019 for (unsigned i
=0; i
< pn
->locals
.size(); ++i
)
6020 ti
.check_local (pn
->locals
[i
]);
6022 // Check and run the autocast expanding visitor.
6023 if (ti
.num_available_autocasts
> 0)
6025 autocast_expanding_visitor
aev (s
, ti
);
6026 var_expand_const_fold_loop (s
, pn
->body
, aev
);
6027 // PR18079, rerun the const-folder / dead-block-remover
6028 // if autocast evaluation enabled a @defined()
6029 if (! s
.unoptimized
)
6032 dead_control_remover
dc (s
, relaxed_p
);
6033 pn
->body
->visit (&dc
);
6034 (void) relaxed_p
; // we judge success later by num_still_unresolved, not this flag
6037 ti
.num_available_autocasts
= 0;
6040 probe_point
* pp
= pn
->sole_location();
6043 ti
.current_function
= 0;
6044 ti
.current_probe
= 0;
6045 ti
.t
= pe_long
; // NB: expected type
6046 pp
->condition
->visit (& ti
);
6049 catch (const semantic_error
& e
)
6051 throw SEMANTIC_ERROR(_F("while processing probe %s",
6052 s
.probes
[j
]->derived_locations(false).c_str())).set_chain(e
);
6055 for (unsigned j
=0; j
<s
.globals
.size(); j
++)
6057 vardecl
* gd
= s
.globals
[j
];
6058 if (gd
->type
== pe_unknown
)
6059 ti
.unresolved (gd
->tok
);
6060 if(gd
->arity
== 0 && gd
->wrap
== true)
6062 throw SEMANTIC_ERROR(_("wrapping not supported for scalars"), gd
->tok
);
6066 if (ti
.num_newly_resolved
== 0) // converged
6068 if (ti
.num_still_unresolved
== 0)
6069 break; // successfully
6070 else if (! ti
.assert_resolvability
)
6072 // PR18079, before we go asserting anything, try to nullify any
6073 // still-unresolved @defined ops.
6074 bool relaxed_p
= true;
6075 const_folder
cf (s
, relaxed_p
, true); // NB: true: collapse remaining @defined's
6077 for (auto it
= s
.probes
.begin(); it
!= s
.probes
.end(); ++it
)
6078 cf
.replace ((*it
)->body
);
6079 for (auto it
= s
.functions
.begin(); it
!= s
.functions
.end(); ++it
)
6080 cf
.replace (it
->second
->body
);
6082 if (! s
.unoptimized
)
6083 semantic_pass_dead_control (s
, relaxed_p
);
6086 ti
.mismatch_complexity
= 0; // reset for next pass
6089 ti
.assert_resolvability
= true; // last pass, with error msgs
6091 ti
.mismatch_complexity
= 0; // print every kind of mismatch
6095 { // unsuccessful conclusion
6101 ti
.mismatch_complexity
= 0; // reset for next pass
6104 return rc
+ s
.num_errors();
6108 struct exp_type_null
: public exp_type_details
6110 uintptr_t id () const { return 0; }
6111 bool expandable() const { return false; }
6112 functioncall
*expand(autocast_op
*, bool) { return NULL
; }
6115 typeresolution_info::typeresolution_info (systemtap_session
& s
):
6116 session(s
), num_newly_resolved(0), num_still_unresolved(0),
6117 num_available_autocasts(0),
6118 assert_resolvability(false), mismatch_complexity(0),
6119 current_function(0), current_probe(0), t(pe_unknown
),
6120 null_type(make_shared
<exp_type_null
>())
6126 typeresolution_info::visit_literal_number (literal_number
* e
)
6128 assert (e
->type
== pe_long
);
6129 if ((t
== e
->type
) || (t
== pe_unknown
))
6132 mismatch (e
->tok
, t
, e
->type
);
6137 typeresolution_info::visit_literal_string (literal_string
* e
)
6139 assert (e
->type
== pe_string
);
6140 if ((t
== e
->type
) || (t
== pe_unknown
))
6143 mismatch (e
->tok
, t
, e
->type
);
6148 typeresolution_info::visit_logical_or_expr (logical_or_expr
*e
)
6150 visit_binary_expression (e
);
6155 typeresolution_info::visit_logical_and_expr (logical_and_expr
*e
)
6157 visit_binary_expression (e
);
6161 typeresolution_info::visit_regex_query (regex_query
*e
)
6163 // NB: result of regex query is an integer!
6164 if (t
== pe_stats
|| t
== pe_string
)
6165 invalid (e
->tok
, t
);
6168 e
->left
->visit (this);
6170 e
->right
->visit (this); // parser ensures this is a literal known at compile time
6172 if (e
->type
== pe_unknown
)
6175 resolved (e
->tok
, e
->type
);
6180 typeresolution_info::visit_compound_expression (compound_expression
* e
)
6182 // Incoming type inference applies to the RHS.
6183 e
->right
->visit(this);
6185 // No incoming data for the LHS.
6187 e
->left
->visit(this);
6192 typeresolution_info::visit_comparison (comparison
*e
)
6194 // NB: result of any comparison is an integer!
6195 if (t
== pe_stats
|| t
== pe_string
)
6196 invalid (e
->tok
, t
);
6198 t
= (e
->right
->type
!= pe_unknown
) ? e
->right
->type
: pe_unknown
;
6199 e
->left
->visit (this);
6200 t
= (e
->left
->type
!= pe_unknown
) ? e
->left
->type
: pe_unknown
;
6201 e
->right
->visit (this);
6203 if (e
->left
->type
!= pe_unknown
&&
6204 e
->right
->type
!= pe_unknown
&&
6205 e
->left
->type
!= e
->right
->type
)
6208 if (e
->type
== pe_unknown
)
6211 resolved (e
->tok
, e
->type
);
6217 typeresolution_info::visit_concatenation (concatenation
*e
)
6219 if (t
!= pe_unknown
&& t
!= pe_string
)
6220 invalid (e
->tok
, t
);
6223 e
->left
->visit (this);
6225 e
->right
->visit (this);
6227 if (e
->type
== pe_unknown
)
6229 e
->type
= pe_string
;
6230 resolved (e
->tok
, e
->type
);
6236 typeresolution_info::visit_assignment (assignment
*e
)
6239 invalid (e
->tok
, t
);
6241 if (e
->op
== "<<<") // stats aggregation
6244 invalid (e
->tok
, t
);
6247 e
->left
->visit (this);
6249 e
->right
->visit (this);
6250 if (e
->type
== pe_unknown
||
6251 e
->type
== pe_stats
)
6254 resolved (e
->tok
, e
->type
);
6258 else if (e
->left
->type
== pe_stats
)
6259 invalid (e
->left
->tok
, e
->left
->type
);
6261 else if (e
->right
->type
== pe_stats
)
6262 invalid (e
->right
->tok
, e
->right
->type
);
6264 else if (e
->op
== "+=" || // numeric only
6276 visit_binary_expression (e
);
6278 else if (e
->op
== ".=" || // string only
6281 if (t
== pe_long
|| t
== pe_stats
)
6282 invalid (e
->tok
, t
);
6285 e
->left
->visit (this);
6287 e
->right
->visit (this);
6288 if (e
->type
== pe_unknown
)
6290 e
->type
= pe_string
;
6291 resolved (e
->tok
, e
->type
);
6294 else if (e
->op
== "=") // overloaded = for string & numeric operands
6297 // logic similar to ternary_expression
6298 exp_type sub_type
= t
;
6300 // Infer types across the l/r values
6301 if (sub_type
== pe_unknown
&& e
->type
!= pe_unknown
)
6304 t
= (sub_type
!= pe_unknown
) ? sub_type
:
6305 (e
->right
->type
!= pe_unknown
) ? e
->right
->type
:
6307 e
->left
->visit (this);
6308 t
= (sub_type
!= pe_unknown
) ? sub_type
:
6309 (e
->left
->type
!= pe_unknown
) ? e
->left
->type
:
6311 e
->right
->visit (this);
6313 if ((sub_type
!= pe_unknown
) && (e
->type
== pe_unknown
))
6316 resolved (e
->tok
, e
->type
);
6318 if ((sub_type
== pe_unknown
) && (e
->left
->type
!= pe_unknown
))
6320 e
->type
= e
->left
->type
;
6321 resolved (e
->tok
, e
->type
);
6324 if (e
->left
->type
!= pe_unknown
&&
6325 e
->right
->type
!= pe_unknown
&&
6326 e
->left
->type
!= e
->right
->type
)
6329 // Propagate type details from the RHS to the assignment
6330 if (e
->type
== e
->right
->type
&&
6331 e
->right
->type_details
&& !e
->type_details
)
6332 resolved_details(e
->right
->type_details
, e
->type_details
);
6334 // Propagate type details from the assignment to the LHS
6335 if (e
->type
== e
->left
->type
&& e
->type_details
)
6337 if (e
->left
->type_details
&&
6338 *e
->left
->type_details
!= *e
->type_details
&&
6339 *e
->left
->type_details
!= *null_type
)
6340 resolved_details(null_type
, e
->left
->type_details
);
6341 else if (!e
->left
->type_details
)
6342 resolved_details(e
->type_details
, e
->left
->type_details
);
6346 throw SEMANTIC_ERROR (_("internal error: unsupported assignment operator ") + (string
)e
->op
);
6351 typeresolution_info::visit_embedded_expr (embedded_expr
*e
)
6353 if (e
->type
== pe_unknown
)
6355 if (e
->tagged_p ("/* string */"))
6356 e
->type
= pe_string
;
6357 else // if (e->tagged_p ("/* long */"))
6360 resolved (e
->tok
, e
->type
);
6366 typeresolution_info::visit_binary_expression (binary_expression
* e
)
6368 if (t
== pe_stats
|| t
== pe_string
)
6369 invalid (e
->tok
, t
);
6372 e
->left
->visit (this);
6374 e
->right
->visit (this);
6376 if (e
->left
->type
!= pe_unknown
&&
6377 e
->right
->type
!= pe_unknown
&&
6378 e
->left
->type
!= e
->right
->type
)
6381 if (e
->type
== pe_unknown
)
6384 resolved (e
->tok
, e
->type
);
6390 typeresolution_info::visit_pre_crement (pre_crement
*e
)
6392 visit_unary_expression (e
);
6397 typeresolution_info::visit_post_crement (post_crement
*e
)
6399 visit_unary_expression (e
);
6404 typeresolution_info::visit_unary_expression (unary_expression
* e
)
6406 if (t
== pe_stats
|| t
== pe_string
)
6407 invalid (e
->tok
, t
);
6410 e
->operand
->visit (this);
6412 if (e
->type
== pe_unknown
)
6415 resolved (e
->tok
, e
->type
);
6421 typeresolution_info::visit_ternary_expression (ternary_expression
* e
)
6423 exp_type sub_type
= t
;
6426 e
->cond
->visit (this);
6428 // Infer types across the true/false arms of the ternary expression.
6430 if (sub_type
== pe_unknown
&& e
->type
!= pe_unknown
)
6433 e
->truevalue
->visit (this);
6435 e
->falsevalue
->visit (this);
6437 if ((sub_type
== pe_unknown
) && (e
->type
!= pe_unknown
))
6438 ; // already resolved
6439 else if ((sub_type
!= pe_unknown
) && (e
->type
== pe_unknown
))
6442 resolved (e
->tok
, e
->type
);
6444 else if ((sub_type
== pe_unknown
) && (e
->truevalue
->type
!= pe_unknown
))
6446 e
->type
= e
->truevalue
->type
;
6447 resolved (e
->tok
, e
->type
);
6449 else if ((sub_type
== pe_unknown
) && (e
->falsevalue
->type
!= pe_unknown
))
6451 e
->type
= e
->falsevalue
->type
;
6452 resolved (e
->tok
, e
->type
);
6454 else if (e
->type
!= sub_type
)
6455 mismatch (e
->tok
, sub_type
, e
->type
);
6457 // Propagate type details from both true/false branches
6458 if (!e
->type_details
&&
6459 e
->type
== e
->truevalue
->type
&& e
->type
== e
->falsevalue
->type
&&
6460 e
->truevalue
->type_details
&& e
->falsevalue
->type_details
&&
6461 *e
->truevalue
->type_details
== *e
->falsevalue
->type_details
)
6462 resolved_details(e
->truevalue
->type_details
, e
->type_details
);
6466 template <class Referrer
, class Referent
>
6467 void resolve_2types (Referrer
* referrer
, Referent
* referent
,
6468 typeresolution_info
* r
, exp_type t
, bool accept_unknown
= false)
6470 exp_type
& re_type
= referrer
->type
;
6471 const token
* re_tok
= referrer
->tok
;
6472 exp_type
& te_type
= referent
->type
;
6474 if (t
!= pe_unknown
&& re_type
== t
&& re_type
== te_type
)
6475 ; // do nothing: all three e->types in agreement
6476 else if (t
== pe_unknown
&& re_type
!= pe_unknown
&& re_type
== te_type
)
6477 ; // do nothing: two known e->types in agreement
6478 else if (re_type
!= pe_unknown
&& te_type
!= pe_unknown
&& re_type
!= te_type
)
6479 r
->mismatch (re_tok
, re_type
, referent
); // referrer-referent
6480 else if (re_type
!= pe_unknown
&& t
!= pe_unknown
&& re_type
!= t
)
6481 r
->mismatch (re_tok
, t
, referent
); // referrer-t
6482 else if (te_type
!= pe_unknown
&& t
!= pe_unknown
&& te_type
!= t
)
6483 r
->mismatch (re_tok
, t
, referent
); // referent-t
6484 else if (re_type
== pe_unknown
&& t
!= pe_unknown
)
6486 // propagate from upstream
6488 r
->resolved (re_tok
, re_type
);
6489 // catch re_type/te_type mismatch later
6491 else if (re_type
== pe_unknown
&& te_type
!= pe_unknown
)
6493 // propagate from referent
6495 r
->resolved (re_tok
, re_type
);
6496 // catch re_type/t mismatch later
6498 else if (re_type
!= pe_unknown
&& te_type
== pe_unknown
)
6500 // propagate to referent
6502 r
->resolved (re_tok
, re_type
, referent
);
6503 // catch re_type/t mismatch later
6505 else if (! accept_unknown
)
6506 r
->unresolved (re_tok
);
6511 typeresolution_info::visit_symbol (symbol
* e
)
6514 if (e
->referent
== 0) // should have been linked or rejected before now
6515 throw SEMANTIC_ERROR (_F("internal error: unresolved symbol '%s'",
6516 e
->name
.to_string().c_str()), e
->tok
);
6518 resolve_2types (e
, e
->referent
, this, t
);
6520 if (e
->type
== e
->referent
->type
)
6523 // If both have type details, then they either must agree;
6524 // otherwise force them both to null.
6525 if (e
->type_details
&& e
->referent
->type_details
&&
6526 *e
->type_details
!= *e
->referent
->type_details
)
6528 this->session
.print_warning(_("Potential type mismatch in reassignment"), e
->tok
);
6530 resolved_details(null_type
, e
->type_details
);
6531 resolved_details(null_type
, e
->referent
->type_details
);
6533 else if (e
->type_details
&& !e
->referent
->type_details
)
6534 resolved_details(e
->type_details
, e
->referent
->type_details
);
6535 else if (!e
->type_details
&& e
->referent
->type_details
)
6536 resolved_details(e
->referent
->type_details
, e
->type_details
);
6543 typeresolution_info::visit_target_register (target_register
* e
)
6546 invalid (e
->tok
, t
);
6547 if (e
->type
== pe_unknown
)
6550 resolved (e
->tok
, e
->type
);
6555 typeresolution_info::visit_target_deref (target_deref
* e
)
6557 // Both the target_deref result as well as the address must both be longs.
6559 invalid (e
->tok
, t
);
6560 e
->addr
->visit (this);
6562 if (e
->type
== pe_unknown
)
6565 resolved (e
->tok
, e
->type
);
6570 typeresolution_info::visit_target_bitfield (target_bitfield
*)
6572 // These are all expanded much earlier.
6577 typeresolution_info::visit_target_symbol (target_symbol
* e
)
6579 // This occurs only if a target symbol was not resolved over in
6580 // tapset.cxx land, that error was properly suppressed, and the
6581 // later unused-expression-elimination pass didn't get rid of it
6582 // either. So we have a target symbol that is believed to be of
6583 // genuine use, yet unresolved by the provider.
6585 // PR18079, or it can happen if a $target expression is nested within
6586 // a @defined() test that has not yet been resolved (but can be soon).
6587 if (! assert_resolvability
)
6589 num_still_unresolved
++;
6593 if (session
.verbose
> 2)
6595 clog
<< _("Resolution problem with ");
6596 if (current_function
)
6598 clog
<< "function " << current_function
->name
<< endl
;
6599 current_function
->body
->print (clog
);
6602 else if (current_probe
)
6604 clog
<< "probe " << *current_probe
->sole_location() << endl
;
6605 current_probe
->body
->print (clog
);
6609 //TRANSLATORS: simply saying not an issue with a probe or function
6610 clog
<< _("other") << endl
;
6613 if (e
->saved_conversion_error
)
6614 session
.print_error (* (e
->saved_conversion_error
));
6616 session
.print_error (SEMANTIC_ERROR(_("unresolved target-symbol expression"), e
->tok
));
6621 typeresolution_info::visit_atvar_op (atvar_op
* e
)
6623 // This occurs only if an @var() was not resolved over in
6624 // tapset.cxx land, that error was properly suppressed, and the
6625 // later unused-expression-elimination pass didn't get rid of it
6626 // either. So we have an @var() that is believed to be of
6627 // genuine use, yet unresolved by the provider.
6629 if (session
.verbose
> 2)
6631 clog
<< _("Resolution problem with ");
6632 if (current_function
)
6634 clog
<< "function " << current_function
->name
<< endl
;
6635 current_function
->body
->print (clog
);
6638 else if (current_probe
)
6640 clog
<< "probe " << *current_probe
->sole_location() << endl
;
6641 current_probe
->body
->print (clog
);
6645 //TRANSLATORS: simply saying not an issue with a probe or function
6646 clog
<< _("other") << endl
;
6649 if (e
->saved_conversion_error
)
6650 session
.print_error (* (e
->saved_conversion_error
));
6652 session
.print_error (SEMANTIC_ERROR(_("unresolved @var() expression"), e
->tok
));
6657 typeresolution_info::visit_defined_op (defined_op
* e
)
6659 // PR18079: if a @defined is still around, it may have a parameter that
6660 // wasn't resolvable one way or another earlier. Maybe an autocast_op.
6661 // Let's give it a visit just in case.
6662 e
->operand
->visit(this);
6664 if (assert_resolvability
)
6665 session
.print_error (SEMANTIC_ERROR(_("unexpected @defined"), e
->tok
));
6667 num_still_unresolved
++;
6672 typeresolution_info::visit_entry_op (entry_op
* e
)
6674 throw SEMANTIC_ERROR(_("internal error: @entry is only valid in .return probes"), e
->tok
);
6679 typeresolution_info::visit_cast_op (cast_op
* e
)
6681 // Like target_symbol, a cast_op shouldn't survive this far
6682 // unless it was not resolved and its value is really needed.
6683 if (e
->saved_conversion_error
)
6684 session
.print_error (* (e
->saved_conversion_error
));
6686 session
.print_error (SEMANTIC_ERROR(_F("type definition '%s' not found in '%s'",
6687 e
->type_name
.to_string().c_str(),
6688 e
->module
.to_string().c_str()), e
->tok
));
6693 typeresolution_info::visit_autocast_op (autocast_op
* e
)
6695 // Like cast_op, a implicit autocast_op shouldn't survive this far
6696 // unless it was not resolved and its value is really needed.
6697 if (assert_resolvability
&& e
->saved_conversion_error
)
6698 session
.print_error (* (e
->saved_conversion_error
));
6699 else if (assert_resolvability
)
6700 session
.print_error (SEMANTIC_ERROR(_("unknown type in dereference"), e
->tok
));
6703 e
->operand
->visit (this);
6705 num_still_unresolved
++;
6706 if (e
->operand
->type_details
&&
6707 e
->operand
->type_details
->expandable())
6708 num_available_autocasts
++;
6713 typeresolution_info::visit_perf_op (perf_op
* e
)
6715 // A perf_op should already be resolved
6716 if (t
== pe_stats
|| t
== pe_string
)
6717 invalid (e
->tok
, t
);
6720 // XXX: ... but but but ... ::visit_defined_op interprets this ->type
6721 // as meaning that @defined(@perf("JUNK JUNK JUNK")) is valid.
6722 // The dwarf_var_expanding_visitor::visit_perf_op() code that validates
6723 // the JUNK parameter is not even called in time.
6725 // (There is no real need to visit our operand - by parser
6726 // construction, it's always a string literal, with its type already
6729 e
->operand
->visit (this);
6734 typeresolution_info::visit_arrayindex (arrayindex
* e
)
6737 symbol
*array
= NULL
;
6738 hist_op
*hist
= NULL
;
6739 classify_indexable(e
->base
, array
, hist
);
6741 // Every hist_op has type [int]:int, that is to say, every hist_op
6742 // is a pseudo-one-dimensional integer array type indexed by
6743 // integers (bucket numbers).
6747 if (e
->indexes
.size() != 1)
6748 unresolved (e
->tok
);
6750 e
->indexes
[0]->visit (this);
6751 if (e
->indexes
[0]->type
!= pe_long
)
6752 unresolved (e
->tok
);
6754 if (e
->type
!= pe_long
)
6757 resolved (e
->tok
, e
->type
);
6762 // Now we are left with "normal" map inference and index checking.
6765 assert (array
->referent
!= 0);
6766 resolve_2types (e
, array
->referent
, this, t
);
6768 // now resolve the array indexes
6770 // if (e->referent->index_types.size() == 0)
6771 // // redesignate referent as array
6772 // e->referent->set_arity (e->indexes.size ());
6774 if (e
->indexes
.size() != array
->referent
->index_types
.size())
6775 unresolved (e
->tok
); // symbol resolution should prevent this
6776 else for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
6780 expression
* ee
= e
->indexes
[i
];
6781 exp_type
& ft
= array
->referent
->index_types
[i
];
6784 exp_type at
= ee
->type
;
6786 if ((at
== pe_string
|| at
== pe_long
) && ft
== pe_unknown
)
6788 // propagate to formal type
6790 resolved (ee
->tok
, ft
, array
->referent
, i
);
6793 invalid (ee
->tok
, at
);
6795 invalid (ee
->tok
, ft
);
6796 if (at
!= pe_unknown
&& ft
!= pe_unknown
&& ft
!= at
)
6797 mismatch (ee
->tok
, ee
->type
, array
->referent
, i
);
6798 if (at
== pe_unknown
)
6799 unresolved (ee
->tok
);
6806 typeresolution_info::visit_functioncall (functioncall
* e
)
6808 if (e
->referents
.empty())
6809 throw SEMANTIC_ERROR (_F("internal error: unresolved function call to '%s'",
6810 e
->function
.to_string().c_str()), e
->tok
);
6812 exp_type original
= t
;
6813 for (unsigned fd
= 0; fd
< e
->referents
.size(); fd
++)
6815 t
= original
; // type may be changed by overloaded functions so restore it
6816 functiondecl
* referent
= e
->referents
[fd
];
6817 resolve_2types (e
, referent
, this, t
, true); // accept unknown type
6819 if (e
->type
== pe_stats
)
6820 invalid (e
->tok
, e
->type
);
6822 const exp_type_ptr
& func_type
= referent
->type_details
;
6823 if (func_type
&& referent
->type
== e
->type
6824 && (!e
->type_details
|| *func_type
!= *e
->type_details
))
6825 resolved_details(referent
->type_details
, e
->type_details
);
6827 // now resolve the function parameters
6828 if (e
->args
.size() != referent
->formal_args
.size())
6829 unresolved (e
->tok
); // symbol resolution should prevent this
6830 else for (unsigned i
=0; i
<e
->args
.size(); i
++)
6832 expression
* ee
= e
->args
[i
];
6833 exp_type
& ft
= referent
->formal_args
[i
]->type
;
6834 const token
* fe_tok
= referent
->formal_args
[i
]->tok
;
6837 exp_type at
= ee
->type
;
6839 if (((at
== pe_string
) || (at
== pe_long
)) && ft
== pe_unknown
)
6841 // propagate to formal arg
6843 resolved (ee
->tok
, ft
, referent
->formal_args
[i
], i
);
6846 invalid (ee
->tok
, at
);
6848 invalid (fe_tok
, ft
);
6849 if (at
!= pe_unknown
&& ft
!= pe_unknown
&& ft
!= at
)
6850 mismatch (ee
->tok
, ee
->type
, referent
->formal_args
[i
], i
);
6851 if (at
== pe_unknown
)
6852 unresolved (ee
->tok
);
6859 typeresolution_info::visit_block (block
* e
)
6861 for (unsigned i
=0; i
<e
->statements
.size(); i
++)
6864 e
->statements
[i
]->visit (this);
6870 typeresolution_info::visit_try_block (try_block
* e
)
6873 e
->try_block
->visit (this);
6874 if (e
->catch_error_var
)
6877 e
->catch_error_var
->visit (this);
6880 e
->catch_block
->visit (this);
6885 typeresolution_info::visit_embeddedcode (embeddedcode
* s
)
6887 // PR11573. If we have survived thus far with a piece of embedded
6888 // code that requires uprobes, we need to track this.
6890 // This is an odd place for this check, as opposed
6891 // to a separate 'optimization' pass, or c_unparser::visit_embeddedcode
6892 // over yonder in pass 3. However, we want to do it during pass 2 so
6893 // that cached sessions also get the uprobes treatment.
6894 if (! session
.need_uprobes
6895 && s
->tagged_p ("/* pragma:uprobes */"))
6897 if (session
.verbose
> 2)
6898 clog
<< _("Activating uprobes support because /* pragma:uprobes */ seen.") << endl
;
6899 session
.need_uprobes
= true;
6902 // PR15065. Likewise, we need to detect /* pragma:tagged_dfa */
6903 // before the gen_dfa_table pass. Again, the typechecking part of
6904 // pass 2 is a good place for this.
6905 if (! session
.need_tagged_dfa
6906 && s
->tagged_p("/* pragma:tagged_dfa */"))
6908 if (session
.verbose
> 2)
6909 clog
<< _("Turning on DFA subexpressions because /* pragma:tagged_dfa */ seen") << endl
;
6910 session
.need_tagged_dfa
= true;
6911 // TODOXXX throw SEMANTIC_ERROR (_("Tagged DFA support is not yet available"), s->tok);
6917 typeresolution_info::visit_if_statement (if_statement
* e
)
6920 e
->condition
->visit (this);
6923 e
->thenblock
->visit (this);
6928 e
->elseblock
->visit (this);
6934 typeresolution_info::visit_for_loop (for_loop
* e
)
6937 if (e
->init
) e
->init
->visit (this);
6939 e
->cond
->visit (this);
6941 if (e
->incr
) e
->incr
->visit (this);
6943 e
->block
->visit (this);
6948 typeresolution_info::visit_foreach_loop (foreach_loop
* e
)
6950 // See also visit_arrayindex.
6951 // This is different in that, being a statement, we can't assign
6952 // a type to the outer array, only propagate to/from the indexes
6954 // if (e->referent->index_types.size() == 0)
6955 // // redesignate referent as array
6956 // e->referent->set_arity (e->indexes.size ());
6958 exp_type wanted_value
= pe_unknown
;
6959 symbol
*array
= NULL
;
6960 hist_op
*hist
= NULL
;
6961 classify_indexable(e
->base
, array
, hist
);
6965 if (e
->indexes
.size() != 1)
6966 unresolved (e
->tok
);
6968 e
->indexes
[0]->visit (this);
6969 if (e
->indexes
[0]->type
!= pe_long
)
6970 unresolved (e
->tok
);
6972 wanted_value
= pe_long
;
6977 if (e
->indexes
.size() != array
->referent
->index_types
.size())
6978 unresolved (e
->tok
); // symbol resolution should prevent this
6981 for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
6983 expression
* ee
= e
->indexes
[i
];
6984 exp_type
& ft
= array
->referent
->index_types
[i
];
6987 exp_type at
= ee
->type
;
6989 if ((at
== pe_string
|| at
== pe_long
) && ft
== pe_unknown
)
6991 // propagate to formal type
6993 resolved (ee
->tok
, ee
->type
, array
->referent
, i
);
6996 invalid (ee
->tok
, at
);
6998 invalid (ee
->tok
, ft
);
6999 if (at
!= pe_unknown
&& ft
!= pe_unknown
&& ft
!= at
)
7000 mismatch (ee
->tok
, ee
->type
, array
->referent
, i
);
7001 if (at
== pe_unknown
)
7002 unresolved (ee
->tok
);
7004 for (unsigned i
=0; i
<e
->array_slice
.size(); i
++)
7005 if (e
->array_slice
[i
])
7007 expression
* ee
= e
->array_slice
[i
];
7008 exp_type
& ft
= array
->referent
->index_types
[i
];
7011 exp_type at
= ee
->type
;
7013 if ((at
== pe_string
|| at
== pe_long
) && ft
== pe_unknown
)
7015 // propagate to formal type
7017 resolved (ee
->tok
, ee
->type
, array
->referent
, i
);
7020 invalid (ee
->tok
, at
);
7022 invalid (ee
->tok
, ft
);
7023 if (at
!= pe_unknown
&& ft
!= pe_unknown
&& ft
!= at
)
7024 mismatch (ee
->tok
, ee
->type
, array
->referent
, i
);
7025 if (at
== pe_unknown
)
7026 unresolved (ee
->tok
);
7030 array
->visit (this);
7031 wanted_value
= array
->type
;
7036 if (wanted_value
== pe_stats
)
7037 invalid(e
->value
->tok
, wanted_value
);
7038 else if (wanted_value
!= pe_unknown
)
7039 check_arg_type(wanted_value
, e
->value
);
7043 e
->value
->visit (this);
7047 /* Prevent @sum etc. aggregate sorting on non-statistics arrays. */
7048 if (wanted_value
!= pe_unknown
)
7049 if (e
->sort_aggr
!= sc_none
&& wanted_value
!= pe_stats
)
7050 invalid (array
->tok
, wanted_value
);
7055 e
->limit
->visit (this);
7059 e
->block
->visit (this);
7064 typeresolution_info::visit_null_statement (null_statement
*)
7070 typeresolution_info::visit_expr_statement (expr_statement
* e
)
7073 e
->value
->visit (this);
7077 struct delete_statement_typeresolution_info
:
7078 public throwing_visitor
7080 typeresolution_info
*parent
;
7081 delete_statement_typeresolution_info (typeresolution_info
*p
):
7082 throwing_visitor (_("invalid operand of delete expression")),
7086 void visit_arrayindex (arrayindex
* e
)
7088 parent
->visit_arrayindex (e
);
7091 void visit_symbol (symbol
* e
)
7093 exp_type ignored
= pe_unknown
;
7094 assert (e
->referent
!= 0);
7095 resolve_2types (e
, e
->referent
, parent
, ignored
);
7101 typeresolution_info::visit_delete_statement (delete_statement
* e
)
7103 delete_statement_typeresolution_info
di (this);
7105 e
->value
->visit (&di
);
7110 typeresolution_info::visit_next_statement (next_statement
*)
7116 typeresolution_info::visit_break_statement (break_statement
*)
7122 typeresolution_info::visit_continue_statement (continue_statement
*)
7128 typeresolution_info::visit_array_in (array_in
* e
)
7130 // all unary operators only work on numerics
7132 t
= pe_unknown
; // array value can be anything
7133 e
->operand
->visit (this);
7135 if (t1
== pe_unknown
&& e
->type
!= pe_unknown
)
7136 ; // already resolved
7137 else if (t1
== pe_string
|| t1
== pe_stats
)
7138 mismatch (e
->tok
, t1
, pe_long
);
7139 else if (e
->type
== pe_unknown
)
7142 resolved (e
->tok
, e
->type
);
7148 typeresolution_info::visit_return_statement (return_statement
* e
)
7150 // This is like symbol, where the referent is
7151 // the return value of the function.
7153 // translation pass will print error
7154 if (current_function
== 0)
7157 exp_type
& e_type
= current_function
->type
;
7158 t
= current_function
->type
;
7162 if (e_type
!= pe_unknown
)
7163 mismatch (e
->tok
, pe_unknown
, current_function
);
7167 e
->value
->visit (this);
7169 if (e_type
!= pe_unknown
&& e
->value
->type
!= pe_unknown
7170 && e_type
!= e
->value
->type
)
7171 mismatch (e
->value
->tok
, e
->value
->type
, current_function
);
7172 if (e_type
== pe_unknown
&&
7173 (e
->value
->type
== pe_long
|| e
->value
->type
== pe_string
))
7175 // propagate non-statistics from value
7176 e_type
= e
->value
->type
;
7177 resolved (e
->value
->tok
, e_type
, current_function
);
7179 if (e
->value
->type
== pe_stats
)
7180 invalid (e
->value
->tok
, e
->value
->type
);
7182 const exp_type_ptr
& value_type
= e
->value
->type_details
;
7183 if (value_type
&& current_function
->type
== e
->value
->type
)
7185 exp_type_ptr
& func_type
= current_function
->type_details
;
7187 // The function can take on the type details of the return value.
7188 resolved_details(value_type
, func_type
);
7189 else if (*func_type
!= *value_type
&& *func_type
!= *null_type
)
7190 // Conflicting return types? NO TYPE FOR YOU!
7191 resolved_details(null_type
, func_type
);
7196 typeresolution_info::visit_print_format (print_format
* e
)
7198 size_t unresolved_args
= 0;
7202 e
->hist
->visit(this);
7205 else if (e
->print_with_format
)
7207 // If there's a format string, we can do both inference *and*
7210 // First we extract the subsequence of formatting components
7211 // which are conversions (not just literal string components)
7213 unsigned expected_num_args
= 0;
7214 std::vector
<print_format::format_component
> components
;
7215 for (size_t i
= 0; i
< e
->components
.size(); ++i
)
7217 if (e
->components
[i
].type
== print_format::conv_unspecified
)
7218 throw SEMANTIC_ERROR (_("Unspecified conversion in print operator format string"),
7220 else if (e
->components
[i
].type
== print_format::conv_literal
)
7222 components
.push_back(e
->components
[i
]);
7223 ++expected_num_args
;
7224 if (e
->components
[i
].widthtype
== print_format::width_dynamic
)
7225 ++expected_num_args
;
7226 if (e
->components
[i
].prectype
== print_format::prec_dynamic
)
7227 ++expected_num_args
;
7230 // Then we check that the number of conversions and the number
7233 if (expected_num_args
!= e
->args
.size())
7234 throw SEMANTIC_ERROR (_("Wrong number of args to formatted print operator"),
7237 // Then we check that the types of the conversions match the types
7240 for (size_t i
= 0; i
< components
.size(); ++i
)
7242 // Check the dynamic width, if specified
7243 if (components
[i
].widthtype
== print_format::width_dynamic
)
7245 check_arg_type (pe_long
, e
->args
[argno
]);
7249 // Check the dynamic precision, if specified
7250 if (components
[i
].prectype
== print_format::prec_dynamic
)
7252 check_arg_type (pe_long
, e
->args
[argno
]);
7256 exp_type wanted
= pe_unknown
;
7258 switch (components
[i
].type
)
7260 case print_format::conv_unspecified
:
7261 case print_format::conv_literal
:
7265 case print_format::conv_pointer
:
7266 case print_format::conv_number
:
7267 case print_format::conv_binary
:
7268 case print_format::conv_char
:
7269 case print_format::conv_memory
:
7270 case print_format::conv_memory_hex
:
7274 case print_format::conv_string
:
7279 assert (wanted
!= pe_unknown
);
7280 check_arg_type (wanted
, e
->args
[argno
]);
7286 // Without a format string, the best we can do is require that
7287 // each argument resolve to a concrete type.
7288 for (size_t i
= 0; i
< e
->args
.size(); ++i
)
7291 e
->args
[i
]->visit (this);
7292 if (e
->args
[i
]->type
== pe_unknown
)
7294 unresolved (e
->args
[i
]->tok
);
7300 if (unresolved_args
== 0)
7302 if (e
->type
== pe_unknown
)
7304 if (e
->print_to_stream
)
7307 e
->type
= pe_string
;
7308 resolved (e
->tok
, e
->type
);
7313 e
->type
= pe_unknown
;
7314 unresolved (e
->tok
);
7320 typeresolution_info::visit_stat_op (stat_op
* e
)
7323 e
->stat
->visit (this);
7324 if (e
->type
== pe_unknown
)
7327 resolved (e
->tok
, e
->type
);
7329 else if (e
->type
!= pe_long
)
7330 mismatch (e
->tok
, pe_long
, e
->type
);
7334 typeresolution_info::visit_hist_op (hist_op
* e
)
7337 e
->stat
->visit (this);
7342 typeresolution_info::check_arg_type (exp_type wanted
, expression
* arg
)
7347 if (arg
->type
== pe_unknown
)
7350 resolved (arg
->tok
, arg
->type
);
7352 else if (arg
->type
!= wanted
)
7354 mismatch (arg
->tok
, wanted
, arg
->type
);
7360 typeresolution_info::check_local (vardecl
* v
)
7364 num_still_unresolved
++;
7365 if (assert_resolvability
)
7367 (SEMANTIC_ERROR (_("array locals not supported, missing global declaration? "), v
->tok
));
7370 if (v
->type
== pe_unknown
)
7371 unresolved (v
->tok
);
7372 else if (v
->type
== pe_stats
)
7374 num_still_unresolved
++;
7375 if (assert_resolvability
)
7377 (SEMANTIC_ERROR (_("stat locals not supported, missing global declaration? "), v
->tok
));
7379 else if (!(v
->type
== pe_long
|| v
->type
== pe_string
))
7380 invalid (v
->tok
, v
->type
);
7385 typeresolution_info::unresolved (const token
* tok
)
7387 num_still_unresolved
++;
7389 if (assert_resolvability
&& mismatch_complexity
<= 0)
7392 msg
<< _("unresolved type ");
7393 session
.print_error (SEMANTIC_ERROR (msg
.str(), tok
));
7399 typeresolution_info::invalid (const token
* tok
, exp_type pe
)
7401 num_still_unresolved
++;
7403 if (assert_resolvability
)
7406 if (tok
&& tok
->type
== tok_operator
)
7407 msg
<< _("invalid operator");
7409 msg
<< _("invalid type ") << pe
;
7410 session
.print_error (SEMANTIC_ERROR (msg
.str(), tok
));
7415 typeresolution_info::mismatch (const binary_expression
* e
)
7417 num_still_unresolved
++;
7419 if (assert_resolvability
&& mismatch_complexity
<= 1)
7422 msg
<< _F("type mismatch: left and right sides don't agree (%s vs %s)",
7423 lex_cast(e
->left
->type
).c_str(), lex_cast(e
->right
->type
).c_str());
7424 session
.print_error (SEMANTIC_ERROR (msg
.str(), e
->tok
));
7426 else if (!assert_resolvability
)
7427 mismatch_complexity
= max(1, mismatch_complexity
);
7430 /* tok token where mismatch occurred
7431 * t1 type we expected (the 'good' type)
7432 * t2 type we received (the 'bad' type)
7435 typeresolution_info::mismatch (const token
* tok
, exp_type t1
, exp_type t2
)
7437 num_still_unresolved
++;
7439 if (assert_resolvability
&& mismatch_complexity
<= 2)
7442 msg
<< _F("type mismatch: expected %s", lex_cast(t1
).c_str());
7443 if (t2
!= pe_unknown
)
7444 msg
<< _F(" but found %s", lex_cast(t2
).c_str());
7445 session
.print_error (SEMANTIC_ERROR (msg
.str(), tok
));
7447 else if (!assert_resolvability
)
7448 mismatch_complexity
= max(2, mismatch_complexity
);
7451 /* tok token where the mismatch happened
7452 * type type we received (the 'bad' type)
7453 * decl declaration of mismatched symbol
7454 * index if index-based (array index or function arg)
7457 typeresolution_info::mismatch (const token
*tok
, exp_type type
,
7458 const symboldecl
* decl
, int index
)
7460 num_still_unresolved
++;
7462 if (assert_resolvability
&& mismatch_complexity
<= 3)
7464 assert(decl
!= NULL
);
7466 // If mismatch is against a function parameter from within the function
7467 // itself (rather than a function call), then the index will be -1. We
7468 // check here if the decl corresponds to one of the params and if so,
7469 // adjust the index.
7470 if (current_function
!= NULL
&& index
== -1)
7472 vector
<vardecl
*>& args
= current_function
->formal_args
;
7473 for (unsigned i
= 0; i
< args
.size() && index
< 0; i
++)
7474 if (args
[i
] == decl
)
7478 // get the declaration's original type and token
7479 const resolved_type
*original
= NULL
;
7480 for (vector
<resolved_type
>::const_iterator it
= resolved_types
.begin();
7481 it
!= resolved_types
.end() && original
== NULL
; ++it
)
7483 if (it
->decl
== decl
&& it
->index
== index
)
7487 // print basic mismatch msg if we couldn't find the decl (this can happen
7488 // for explicitly typed decls e.g. myvar:long or for fabricated (already
7489 // resolved) decls e.g. __perf_read_*)
7490 if (original
== NULL
)
7492 session
.print_error (SEMANTIC_ERROR (
7493 _F("type mismatch: expected %s but found %s",
7494 lex_cast(type
).c_str(),
7495 lex_cast(decl
->type
).c_str()),
7500 // print where mismatch happened and chain with origin of decl type
7505 msg
<< _F("index %d ", index
);
7506 msg
<< _F("type mismatch (%s)", lex_cast(type
).c_str());
7507 semantic_error
err(ERR_SRC
, msg
.str(), tok
);
7509 stringstream chain_msg
;
7510 chain_msg
<< _("type");
7512 chain_msg
<< _F(" of index %d", index
);
7513 chain_msg
<< _F(" was first inferred here (%s)",
7514 lex_cast(decl
->type
).c_str());
7515 semantic_error
chain(ERR_SRC
, chain_msg
.str(), original
->tok
);
7517 err
.set_chain(chain
);
7518 session
.print_error (err
);
7520 else if (!assert_resolvability
)
7521 mismatch_complexity
= max(3, mismatch_complexity
);
7525 /* tok token where resolution occurred
7526 * type type to which we resolved
7527 * decl declaration of resolved symbol
7528 * index if index-based (array index or function arg)
7531 typeresolution_info::resolved (const token
*tok
, exp_type t
,
7532 const symboldecl
* decl
, int index
)
7534 num_newly_resolved
++;
7536 if (session
.verbose
> 4)
7537 clog
<< "resolved type " << t
<< " to " << *tok
<< endl
;
7539 // We only use the resolved_types vector to give better mismatch messages
7540 // involving symbols. So don't bother adding it if we're not given a decl
7543 // As a fail-safe, if the decl & index is already in the vector, then
7544 // modify it instead of adding another one to ensure uniqueness. This
7545 // should never happen since we only call resolved once for each decl &
7546 // index, but better safe than sorry. (IE. if it does happen, better have
7547 // the latest resolution info for better mismatch reporting later).
7548 for (unsigned i
= 0; i
< resolved_types
.size(); i
++)
7550 if (resolved_types
[i
].decl
== decl
7551 && resolved_types
[i
].index
== index
)
7553 resolved_types
[i
].tok
= tok
;
7557 resolved_type
res(tok
, decl
, index
);
7558 resolved_types
.push_back(res
);
7563 typeresolution_info::resolved_details (const exp_type_ptr
& src
,
7566 num_newly_resolved
++;
7570 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */