1 // elaboration functions
2 // Copyright (C) 2005-2015 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->body
= deep_copy_visitor::deep_copy(p
->body
);
74 // make a copy for subclasses which want to rewrite the location
76 l
= new probe_point(*l
);
77 this->locations
.push_back (l
);
82 derived_probe::printsig (ostream
& o
) const
89 derived_probe::printsig_nested (ostream
& o
) const
91 // We'd like to enclose the probe derivation chain in a /* */
92 // comment delimiter. But just printing /* base->printsig() */ is
93 // not enough, since base might itself be a derived_probe. So we,
94 // er, "cleverly" encode our nesting state as a formatting flag for
96 ios::fmtflags f
= o
.flags (ios::internal
);
97 if (f
& ios::internal
)
116 derived_probe::collect_derivation_chain (std::vector
<probe
*> &probes_list
) const
118 probes_list
.push_back(const_cast<derived_probe
*>(this));
119 base
->collect_derivation_chain(probes_list
);
124 derived_probe::collect_derivation_pp_chain (std::vector
<probe_point
*> &pp_list
) const
126 pp_list
.push_back(const_cast<probe_point
*>(this->sole_location()));
127 base
->collect_derivation_pp_chain(pp_list
);
132 derived_probe::derived_locations (bool firstFrom
)
135 vector
<probe_point
*> reference_point
;
136 collect_derivation_pp_chain(reference_point
);
137 if (reference_point
.size() > 0)
138 for(unsigned i
=1; i
<reference_point
.size(); ++i
)
140 if (firstFrom
|| i
>1)
142 o
<< reference_point
[i
]->str(false); // no ?,!,etc
149 derived_probe::sole_location () const
151 if (locations
.size() == 0 || locations
.size() > 1)
152 throw SEMANTIC_ERROR (_N("derived_probe with no locations",
153 "derived_probe with too many locations",
154 locations
.size()), this->tok
);
161 derived_probe::script_location () const
163 // This feeds function::pn() in the tapset, which is documented as the
164 // script-level probe point expression, *after wildcard expansion*.
165 vector
<probe_point
*> chain
;
166 collect_derivation_pp_chain (chain
);
168 // Go backwards until we hit the first well-formed probe point
169 for (int i
=chain
.size()-1; i
>=0; i
--)
170 if (chain
[i
]->well_formed
)
173 // If that didn't work, just fallback to -something-.
174 return sole_location();
179 derived_probe::emit_privilege_assertion (translator_output
* o
)
181 // Emit code which will cause compilation to fail if it is compiled in
182 // unprivileged mode.
183 o
->newline() << "#if ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPDEV) && \\";
184 o
->newline() << " ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPSYS)";
185 o
->newline() << "#error Internal Error: Probe ";
186 probe::printsig (o
->line());
187 o
->line() << " generated in --unprivileged mode";
188 o
->newline() << "#endif";
193 derived_probe::emit_process_owner_assertion (translator_output
* o
)
195 // Emit code which will abort should the current target not belong to the
196 // user in unprivileged mode.
197 o
->newline() << "#if ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPDEV) && \\";
198 o
->newline() << " ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPSYS)";
199 o
->newline(1) << "if (! is_myproc ()) {";
200 o
->newline(1) << "snprintf(c->error_buffer, sizeof(c->error_buffer),";
201 o
->newline() << " \"Internal Error: Process %d does not belong to user %d in probe %s in --unprivileged mode\",";
202 o
->newline() << " current->tgid, _stp_uid, c->probe_point);";
203 o
->newline() << "c->last_error = c->error_buffer;";
204 // NB: since this check occurs before probe locking, its exit should
205 // not be a "goto out", which would attempt unlocking.
206 o
->newline() << "return;";
207 o
->newline(-1) << "}";
208 o
->newline(-1) << "#endif";
212 derived_probe::print_dupe_stamp_unprivileged(ostream
& o
)
214 o
<< _("unprivileged users: authorized") << endl
;
218 derived_probe::print_dupe_stamp_unprivileged_process_owner(ostream
& o
)
220 o
<< _("unprivileged users: authorized for process owner") << endl
;
223 // ------------------------------------------------------------------------
224 // Members of derived_probe_builder
227 derived_probe_builder::build_with_suffix(systemtap_session
& sess
,
229 probe_point
* location
,
230 literal_map_t
const & parameters
,
231 std::vector
<derived_probe
*>
233 std::vector
<probe_point::component
*>
235 // XXX perhaps build the probe if suffix is empty?
236 // if (suffix.empty()) {
237 // build (sess, use, location, parameters, finished_results);
240 throw SEMANTIC_ERROR (_("invalid suffix for probe"));
244 derived_probe_builder::get_param (literal_map_t
const & params
,
246 interned_string
& value
)
248 literal_map_t::const_iterator i
= params
.find (key
);
249 if (i
== params
.end())
251 literal_string
* ls
= dynamic_cast<literal_string
*>(i
->second
);
260 derived_probe_builder::get_param (literal_map_t
const & params
,
264 literal_map_t::const_iterator i
= params
.find (key
);
265 if (i
== params
.end())
267 if (i
->second
== NULL
)
269 literal_number
* ln
= dynamic_cast<literal_number
*>(i
->second
);
278 derived_probe_builder::has_null_param (literal_map_t
const & params
,
281 literal_map_t::const_iterator i
= params
.find(key
);
282 return (i
!= params
.end() && i
->second
== NULL
);
286 derived_probe_builder::has_param (literal_map_t
const & params
,
289 return (params
.find(key
) != params
.end());
292 // ------------------------------------------------------------------------
293 // Members of match_key.
295 match_key::match_key(interned_string n
)
297 have_parameter(false),
298 parameter_type(pe_unknown
)
302 match_key::match_key(probe_point::component
const & c
)
304 have_parameter(c
.arg
!= NULL
),
305 parameter_type(c
.arg
? c
.arg
->type
: pe_unknown
)
310 match_key::with_number()
312 have_parameter
= true;
313 parameter_type
= pe_long
;
318 match_key::with_string()
320 have_parameter
= true;
321 parameter_type
= pe_string
;
326 match_key::str() const
330 switch (parameter_type
)
332 case pe_string
: return n
+ "(string)";
333 case pe_long
: return n
+ "(number)";
334 default: return n
+ "(...)";
340 match_key::operator<(match_key
const & other
) const
342 return ((name
< other
.name
)
344 || (name
== other
.name
345 && have_parameter
< other
.have_parameter
)
347 || (name
== other
.name
348 && have_parameter
== other
.have_parameter
349 && parameter_type
< other
.parameter_type
));
353 // NB: these are only used in the probe point name components, where
354 // only "*" is permitted.
356 // Within module("bar"), function("foo"), process("baz") strings, real
357 // wildcards are permitted too. See also util.h:contains_glob_chars
360 isglob(interned_string str
)
362 return(str
.find('*') != str
.npos
);
366 isdoubleglob(interned_string str
)
368 return(str
.find("**") != str
.npos
);
372 match_key::globmatch(match_key
const & other
) const
374 const string
& name_str
= name
;
375 const string
& other_str
= other
.name
;
377 return ((fnmatch(name_str
.c_str(), other_str
.c_str(), FNM_NOESCAPE
) == 0)
378 && have_parameter
== other
.have_parameter
379 && parameter_type
== other
.parameter_type
);
382 // ------------------------------------------------------------------------
383 // Members of match_node
384 // ------------------------------------------------------------------------
386 match_node::match_node() :
387 privilege(privilege_t (pr_stapdev
| pr_stapsys
))
392 match_node::bind(match_key
const & k
)
395 throw SEMANTIC_ERROR(_("invalid use of wildcard probe point component"));
397 map
<match_key
, match_node
*>::const_iterator i
= sub
.find(k
);
400 match_node
* n
= new match_node();
401 sub
.insert(make_pair(k
, n
));
406 match_node::bind(derived_probe_builder
* e
)
412 match_node::bind(interned_string k
)
414 return bind(match_key(k
));
418 match_node::bind_str(string
const & k
)
420 return bind(match_key(k
).with_string());
424 match_node::bind_num(string
const & k
)
426 return bind(match_key(k
).with_number());
430 match_node::bind_privilege(privilege_t p
)
437 match_node::find_and_build (systemtap_session
& s
,
438 probe
* p
, probe_point
*loc
, unsigned pos
,
439 vector
<derived_probe
*>& results
)
441 assert (pos
<= loc
->components
.size());
442 if (pos
== loc
->components
.size()) // matched all probe point components so far
447 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
448 alternatives
+= string(" ") + i
->first
.str();
450 throw SEMANTIC_ERROR (_F("probe point truncated (follow: %s)",
451 alternatives
.c_str()),
452 loc
->components
.back()->tok
);
455 if (! pr_contains (privilege
, s
.privilege
))
457 throw SEMANTIC_ERROR (_F("probe point is not allowed for --privilege=%s",
458 pr_name (s
.privilege
)),
459 loc
->components
.back()->tok
);
462 literal_map_t param_map
;
463 for (unsigned i
=0; i
<pos
; i
++)
464 param_map
[loc
->components
[i
]->functor
] = loc
->components
[i
]->arg
;
467 // Iterate over all bound builders
468 for (unsigned k
=0; k
<ends
.size(); k
++)
470 derived_probe_builder
*b
= ends
[k
];
471 b
->build (s
, p
, loc
, param_map
, results
);
474 else if (isdoubleglob(loc
->components
[pos
]->functor
)) // ** wildcard?
476 unsigned int num_results
= results
.size();
478 // When faced with "foo**bar", we try "foo*bar" and "foo*.**bar"
480 const probe_point::component
*comp
= loc
->components
[pos
];
481 string functor
= comp
->functor
;
482 size_t glob_start
= functor
.find("**");
483 size_t glob_end
= functor
.find_first_not_of('*', glob_start
);
484 string prefix
= functor
.substr(0, glob_start
);
485 string suffix
= ((glob_end
!= string::npos
) ?
486 functor
.substr(glob_end
) : "");
488 // Synthesize "foo*bar"
489 probe_point
*simple_pp
= new probe_point(*loc
);
490 probe_point::component
*simple_comp
= new probe_point::component(*comp
);
491 simple_comp
->functor
= prefix
+ "*" + suffix
;
492 simple_comp
->from_glob
= true;
493 simple_pp
->components
[pos
] = simple_comp
;
496 find_and_build (s
, p
, simple_pp
, pos
, results
);
498 catch (const semantic_error
& e
)
500 // Ignore semantic_errors.
503 // Cleanup if we didn't find anything
504 if (results
.size() == num_results
)
510 num_results
= results
.size();
512 // Synthesize "foo*.**bar"
513 // NB: any component arg should attach to the latter part only
514 probe_point
*expanded_pp
= new probe_point(*loc
);
515 probe_point::component
*expanded_comp_pre
= new probe_point::component(*comp
);
516 expanded_comp_pre
->functor
= prefix
+ "*";
517 expanded_comp_pre
->from_glob
= true;
518 expanded_comp_pre
->arg
= NULL
;
519 probe_point::component
*expanded_comp_post
= new probe_point::component(*comp
);
520 expanded_comp_post
->functor
= string("**") + suffix
;
521 expanded_pp
->components
[pos
] = expanded_comp_pre
;
522 expanded_pp
->components
.insert(expanded_pp
->components
.begin() + pos
+ 1,
526 find_and_build (s
, p
, expanded_pp
, pos
, results
);
528 catch (const semantic_error
& e
)
530 // Ignore semantic_errors.
533 // Cleanup if we didn't find anything
534 if (results
.size() == num_results
)
537 delete expanded_comp_pre
;
538 delete expanded_comp_post
;
541 // Try suffix expansion only if no matches found:
542 if (num_results
== results
.size())
543 this->try_suffix_expansion (s
, p
, loc
, pos
, results
);
545 if (! loc
->optional
&& num_results
== results
.size())
547 // We didn't find any wildcard matches (since the size of
548 // the result vector didn't change). Throw an error.
549 string sugs
= suggest_functors(s
, functor
);
550 throw SEMANTIC_ERROR (_F("probe point mismatch: didn't find any wildcard matches%s",
551 sugs
.empty() ? "" : (" (similar: " + sugs
+ ")").c_str()),
555 else if (isglob(loc
->components
[pos
]->functor
)) // wildcard?
557 match_key
match (* loc
->components
[pos
]);
559 // Call find_and_build for each possible match. Ignore errors -
560 // unless we don't find any match.
561 unsigned int num_results
= results
.size();
562 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
564 const match_key
& subkey
= i
->first
;
565 match_node
* subnode
= i
->second
;
567 assert_no_interrupts();
569 if (match
.globmatch(subkey
))
572 clog
<< _F("wildcard '%s' matched '%s'",
573 loc
->components
[pos
]->functor
.to_string().c_str(),
574 subkey
.name
.to_string().c_str()) << endl
;
576 // When we have a wildcard, we need to create a copy of
577 // the probe point. Then we'll create a copy of the
578 // wildcard component, and substitute the non-wildcard
580 probe_point
*non_wildcard_pp
= new probe_point(*loc
);
581 probe_point::component
*non_wildcard_component
582 = new probe_point::component(*loc
->components
[pos
]);
583 non_wildcard_component
->functor
= subkey
.name
;
584 non_wildcard_component
->from_glob
= true;
585 non_wildcard_pp
->components
[pos
] = non_wildcard_component
;
587 // NB: probe conditions are not attached at the wildcard
588 // (component/functor) level, but at the overall
589 // probe_point level.
591 unsigned int inner_results
= results
.size();
593 // recurse (with the non-wildcard probe point)
596 subnode
->find_and_build (s
, p
, non_wildcard_pp
, pos
+1,
599 catch (const semantic_error
& e
)
601 // Ignore semantic_errors while expanding wildcards.
602 // If we get done and nothing was expanded, the code
603 // following the loop will complain.
606 if (results
.size() == inner_results
)
608 // If this wildcard didn't match, cleanup.
609 delete non_wildcard_pp
;
610 delete non_wildcard_component
;
615 // Try suffix expansion only if no matches found:
616 if (num_results
== results
.size())
617 this->try_suffix_expansion (s
, p
, loc
, pos
, results
);
619 if (! loc
->optional
&& num_results
== results
.size())
621 // We didn't find any wildcard matches (since the size of
622 // the result vector didn't change). Throw an error.
623 string sugs
= suggest_functors(s
, loc
->components
[pos
]->functor
);
624 throw SEMANTIC_ERROR (_F("probe point mismatch: didn't find any wildcard matches%s",
625 sugs
.empty() ? "" : (" (similar: " + sugs
+ ")").c_str()),
626 loc
->components
[pos
]->tok
);
631 match_key
match (* loc
->components
[pos
]);
632 sub_map_iterator_t i
= sub
.find (match
);
634 if (i
!= sub
.end()) // match found
636 match_node
* subnode
= i
->second
;
638 subnode
->find_and_build (s
, p
, loc
, pos
+1, results
);
642 unsigned int num_results
= results
.size();
643 this->try_suffix_expansion (s
, p
, loc
, pos
, results
);
645 // XXX: how to correctly report alternatives + position numbers
646 // for alias suffixes? file a separate PR to address the issue
647 if (! loc
->optional
&& num_results
== results
.size())
649 // We didn't find any alias suffixes (since the size of the
650 // result vector didn't change). Throw an error.
651 string sugs
= suggest_functors(s
, loc
->components
[pos
]->functor
);
652 throw SEMANTIC_ERROR (_F("probe point mismatch%s",
653 sugs
.empty() ? "" : (" (similar: " + sugs
+ ")").c_str()),
654 loc
->components
[pos
]->tok
);
660 match_node::suggest_functors(systemtap_session
& s
, string functor
)
662 // only use prefix if globby (and prefix is non-empty)
663 size_t glob
= functor
.find('*');
664 if (glob
!= string::npos
&& glob
!= 0)
669 // PR18577: There isn't any point in generating a suggestion list if
670 // we're not going to display it.
671 if ((s
.dump_mode
== systemtap_session::dump_matched_probes
672 || s
.dump_mode
== systemtap_session::dump_matched_probes_vars
)
676 set
<string
> functors
;
677 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
679 string ftor
= i
->first
.str();
680 if (ftor
.find('(') != string::npos
) // trim any parameter
681 ftor
.erase(ftor
.find('('));
682 functors
.insert(ftor
);
684 return levenshtein_suggest(functor
, functors
, 5); // print top 5
688 match_node::try_suffix_expansion (systemtap_session
& s
,
689 probe
*p
, probe_point
*loc
, unsigned pos
,
690 vector
<derived_probe
*>& results
)
692 // PR12210: match alias suffixes. If the components thus far
693 // have been matched, but there is an additional unknown
694 // suffix, we have a potential alias suffix on our hands. We
695 // need to expand the preceding components as probe aliases,
696 // reattach the suffix, and re-run derive_probes() on the
697 // resulting expansion. This is done by the routine
698 // build_with_suffix().
700 if (strverscmp(s
.compatible
.c_str(), "2.0") >= 0)
702 // XXX: technically, param_map isn't used here. So don't
703 // bother actually assembling it unless some
704 // derived_probe_builder appears that actually takes
705 // suffixes *and* consults parameters (currently no such
707 literal_map_t param_map
;
708 // for (unsigned i=0; i<pos; i++)
709 // param_map[loc->components[i]->functor] = loc->components[i]->arg;
712 vector
<probe_point::component
*> suffix (loc
->components
.begin()+pos
,
713 loc
->components
.end());
715 // Multiple derived_probe_builders may be bound at a
716 // match_node due to the possibility of multiply defined
718 for (unsigned k
=0; k
< ends
.size(); k
++)
720 derived_probe_builder
*b
= ends
[k
];
723 b
->build_with_suffix (s
, p
, loc
, param_map
, results
, suffix
);
725 catch (const recursive_expansion_error
&e
)
728 throw semantic_error(e
);
730 catch (const semantic_error
&e
)
732 // Adjust source coordinate and re-throw:
734 throw semantic_error(e
.errsrc
, e
.what(), loc
->components
[pos
]->tok
);
742 match_node::build_no_more (systemtap_session
& s
)
744 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
745 i
->second
->build_no_more (s
);
746 for (unsigned k
=0; k
<ends
.size(); k
++)
748 derived_probe_builder
*b
= ends
[k
];
749 b
->build_no_more (s
);
754 match_node::dump (systemtap_session
&s
, const string
&name
)
756 // Dump this node, if it is complete.
757 for (unsigned k
=0; k
<ends
.size(); k
++)
759 // Don't print aliases at all (for now) until we can figure out how to determine whether
760 // the probes they resolve to are ok in unprivileged mode.
761 if (ends
[k
]->is_alias ())
764 // In unprivileged mode, don't show the probes which are not allowed for unprivileged
766 if (pr_contains (privilege
, s
.privilege
))
768 cout
<< name
<< endl
;
769 break; // we need only print one instance.
773 // Recursively dump the children of this node
777 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
779 i
->second
->dump (s
, name
+ dot
+ i
->first
.str());
784 // ------------------------------------------------------------------------
786 // ------------------------------------------------------------------------
788 struct alias_derived_probe
: public derived_probe
790 alias_derived_probe (probe
* base
, probe_point
*l
, const probe_alias
*a
,
791 const vector
<probe_point::component
*> *suffix
= 0);
792 ~alias_derived_probe();
794 void upchuck () { throw SEMANTIC_ERROR (_("inappropriate"), this->tok
); }
796 // Alias probes are immediately expanded to other derived_probe
797 // types, and are not themselves emitted or listed in
798 // systemtap_session.probes
800 void join_group (systemtap_session
&) { upchuck (); }
802 virtual const probe_alias
*get_alias () const { return alias
; }
803 virtual probe_point
*get_alias_loc () const { return alias_loc
; }
804 virtual probe_point
*sole_location () const;
807 const probe_alias
*alias
; // Used to check for recursion
808 probe_point
*alias_loc
; // Hack to recover full probe name
812 alias_derived_probe::alias_derived_probe(probe
*base
, probe_point
*l
,
813 const probe_alias
*a
,
814 const vector
<probe_point::component
*>
816 derived_probe (base
, l
), alias(a
)
818 // XXX pretty nasty -- this was cribbed from printscript() in main.cxx
819 assert (alias
->alias_names
.size() >= 1);
820 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
821 alias_loc
->well_formed
= true;
822 vector
<probe_point::component
*>::const_iterator it
;
823 for (it
= suffix
->begin(); it
!= suffix
->end(); ++it
)
825 alias_loc
->components
.push_back(*it
);
826 if (isglob((*it
)->functor
))
827 alias_loc
->well_formed
= false; // needs further derivation
831 alias_derived_probe::~alias_derived_probe ()
838 alias_derived_probe::sole_location () const
840 return const_cast<probe_point
*>(alias_loc
);
845 alias_expansion_builder::build(systemtap_session
& sess
,
847 probe_point
* location
,
848 literal_map_t
const & parameters
,
849 vector
<derived_probe
*> & finished_results
)
851 vector
<probe_point::component
*> empty_suffix
;
852 build_with_suffix (sess
, use
, location
, parameters
,
853 finished_results
, empty_suffix
);
857 alias_expansion_builder::build_with_suffix(systemtap_session
& sess
,
859 probe_point
* location
,
860 literal_map_t
const &,
861 vector
<derived_probe
*>
863 vector
<probe_point::component
*>
866 // Don't build the alias expansion if infinite recursion is detected.
867 if (checkForRecursiveExpansion (use
)) {
869 msg
<< _F("recursive loop in alias expansion of %s at %s",
870 lex_cast(*location
).c_str(), lex_cast(location
->components
.front()->tok
->location
).c_str());
871 // semantic_errors thrown here might be ignored, so we need a special class:
872 throw recursive_expansion_error (msg
.str());
873 // XXX The point of throwing this custom error is to suppress a
874 // cascade of "probe mismatch" messages that appear in addition to
875 // the error. The current approach suppresses most of the error
876 // cascade, but leaves one spurious error; in any case, the way
877 // this particular error is reported could be improved.
880 // We're going to build a new probe and wrap it up in an
881 // alias_expansion_probe so that the expansion loop recognizes it as
882 // such and re-expands its expansion.
884 alias_derived_probe
* n
= new alias_derived_probe (use
, location
/* soon overwritten */, this->alias
, &suffix
);
885 n
->body
= new block();
887 // The new probe gets a deep copy of the location list of the alias
888 // (with incoming condition joined) plus the suffix (if any),
889 n
->locations
.clear();
890 for (unsigned i
=0; i
<alias
->locations
.size(); i
++)
892 probe_point
*pp
= new probe_point(*alias
->locations
[i
]);
893 pp
->components
.insert(pp
->components
.end(), suffix
.begin(), suffix
.end());
894 pp
->condition
= add_condition (pp
->condition
, location
->condition
);
895 n
->locations
.push_back(pp
);
898 // the token location of the alias,
899 n
->tok
= location
->components
.front()->tok
;
901 // and statements representing the concatenation of the alias'
902 // body with the use's.
904 // NB: locals are *not* copied forward, from either alias or
905 // use. The expansion should have its locals re-inferred since
906 // there's concatenated code here and we only want one vardecl per
907 // resulting variable.
909 if (alias
->epilogue_style
)
910 n
->body
= new block (use
->body
, alias
->body
);
912 n
->body
= new block (alias
->body
, use
->body
);
914 unsigned old_num_results
= finished_results
.size();
915 // If expanding for an alias suffix, be sure to pass on any errors
916 // to the caller instead of printing them in derive_probes():
917 derive_probes (sess
, n
, finished_results
, location
->optional
, !suffix
.empty());
919 // Check whether we resolved something. If so, put the
920 // whole library into the queue if not already there.
921 if (finished_results
.size() > old_num_results
)
923 stapfile
*f
= alias
->tok
->location
.file
;
924 if (find (sess
.files
.begin(), sess
.files
.end(), f
)
926 sess
.files
.push_back (f
);
931 alias_expansion_builder::checkForRecursiveExpansion (probe
*use
)
933 // Collect the derivation chain of this probe.
934 vector
<probe
*>derivations
;
935 use
->collect_derivation_chain (derivations
);
937 // Check all probe points in the alias expansion against the currently-being-expanded probe point
938 // of each of the probes in the derivation chain, looking for a match. This
939 // indicates infinite recursion.
940 // The first element of the derivation chain will be the derived_probe representing 'use', so
941 // start the search with the second element.
942 assert (derivations
.size() > 0);
943 assert (derivations
[0] == use
);
944 for (unsigned d
= 1; d
< derivations
.size(); ++d
) {
945 if (use
->get_alias() == derivations
[d
]->get_alias())
946 return true; // recursion detected
952 // ------------------------------------------------------------------------
954 // ------------------------------------------------------------------------
956 static unsigned max_recursion
= 100;
962 recursion_guard(unsigned & i
) : i(i
)
964 if (i
> max_recursion
)
965 throw SEMANTIC_ERROR(_("recursion limit reached"));
974 // The match-and-expand loop.
976 derive_probes (systemtap_session
& s
,
977 probe
*p
, vector
<derived_probe
*>& dps
,
981 // We need a static to track whether the current probe is optional so that
982 // even if we recurse into derive_probes with optional = false, errors will
983 // still be ignored. The undo_parent_optional bool ensures we reset the
984 // static at the same level we had it set.
985 static bool parent_optional
= false;
986 bool undo_parent_optional
= false;
988 if (optional
&& !parent_optional
)
990 parent_optional
= true;
991 undo_parent_optional
= true;
994 vector
<semantic_error
> optional_errs
;
996 for (unsigned i
= 0; i
< p
->locations
.size(); ++i
)
998 assert_no_interrupts();
1000 probe_point
*loc
= p
->locations
[i
];
1003 clog
<< "derive-probes " << *loc
<< endl
;
1007 unsigned num_atbegin
= dps
.size();
1011 s
.pattern_root
->find_and_build (s
, p
, loc
, 0, dps
); // <-- actual derivation!
1013 catch (const semantic_error
& e
)
1015 if (!loc
->optional
&& !parent_optional
)
1016 throw semantic_error(e
);
1017 else /* tolerate failure for optional probe */
1019 // remember err, we will print it (in catch block) if any
1020 // non-optional loc fails to resolve
1021 semantic_error
err(ERR_SRC
, _("while resolving probe point"),
1022 loc
->components
[0]->tok
, NULL
, &e
);
1023 optional_errs
.push_back(err
);
1028 unsigned num_atend
= dps
.size();
1030 if (! (loc
->optional
||parent_optional
) && // something required, but
1031 num_atbegin
== num_atend
) // nothing new derived!
1032 throw SEMANTIC_ERROR (_("no match"));
1034 if (loc
->sufficient
&& (num_atend
> num_atbegin
))
1038 clog
<< "Probe point ";
1039 p
->locations
[i
]->print(clog
);
1040 clog
<< " sufficient, skipped";
1041 for (unsigned j
= i
+1; j
< p
->locations
.size(); ++j
)
1044 p
->locations
[j
]->print(clog
);
1048 break; // we need not try to derive for any other locations
1051 catch (const semantic_error
& e
)
1053 // The rethrow_errors parameter lets the caller decide an
1054 // alternative to printing the error. This is necessary when
1055 // calling derive_probes() recursively during expansion of
1056 // an alias with suffix -- any message printed here would
1057 // point to the alias declaration and not the invalid suffix
1058 // usage, so the caller needs to catch the error themselves
1059 // and print a more appropriate message.
1062 throw semantic_error(e
);
1064 // Only output in dump mode if -vv is supplied:
1065 else if (!s
.dump_mode
|| (s
.verbose
> 1))
1067 // print this one manually first because it's more important than
1068 // the optional errs
1069 semantic_error
err(ERR_SRC
, _("while resolving probe point"),
1070 loc
->components
[0]->tok
, NULL
, &e
);
1073 // print optional errs accumulated while visiting other probe points
1074 for (vector
<semantic_error
>::const_iterator it
= optional_errs
.begin();
1075 it
!= optional_errs
.end(); ++it
)
1083 if (undo_parent_optional
)
1084 parent_optional
= false;
1089 // ------------------------------------------------------------------------
1091 // Indexable usage checks
1094 struct symbol_fetcher
1095 : public throwing_visitor
1099 symbol_fetcher (symbol
*&sym
): sym(sym
)
1102 void visit_symbol (symbol
* e
)
1107 void visit_arrayindex (arrayindex
* e
)
1109 e
->base
->visit (this);
1112 void throwone (const token
* t
)
1114 throw SEMANTIC_ERROR (_("Expecting symbol or array index expression"), t
);
1119 get_symbol_within_expression (expression
*e
)
1122 symbol_fetcher
fetcher(sym
);
1123 e
->visit (&fetcher
);
1124 return sym
; // NB: may be null!
1128 get_symbol_within_indexable (indexable
*ix
)
1130 symbol
*array
= NULL
;
1131 hist_op
*hist
= NULL
;
1132 classify_indexable(ix
, array
, hist
);
1136 return get_symbol_within_expression (hist
->stat
);
1139 struct mutated_var_collector
1140 : public traversing_visitor
1142 set
<vardecl
*> * mutated_vars
;
1144 mutated_var_collector (set
<vardecl
*> * mm
)
1148 void visit_assignment(assignment
* e
)
1150 if (e
->type
== pe_stats
&& e
->op
== "<<<")
1152 vardecl
*vd
= get_symbol_within_expression (e
->left
)->referent
;
1154 mutated_vars
->insert (vd
);
1156 traversing_visitor::visit_assignment(e
);
1159 void visit_arrayindex (arrayindex
*e
)
1161 if (is_active_lvalue (e
))
1164 if (e
->base
->is_symbol (sym
))
1165 mutated_vars
->insert (sym
->referent
);
1167 throw SEMANTIC_ERROR(_("Assignment to read-only histogram bucket"), e
->tok
);
1169 traversing_visitor::visit_arrayindex (e
);
1174 struct no_var_mutation_during_iteration_check
1175 : public traversing_visitor
1177 systemtap_session
& session
;
1178 map
<functiondecl
*,set
<vardecl
*> *> & function_mutates_vars
;
1179 vector
<vardecl
*> vars_being_iterated
;
1181 no_var_mutation_during_iteration_check
1182 (systemtap_session
& sess
,
1183 map
<functiondecl
*,set
<vardecl
*> *> & fmv
)
1184 : session(sess
), function_mutates_vars (fmv
)
1187 void visit_arrayindex (arrayindex
*e
)
1189 if (is_active_lvalue(e
))
1191 vardecl
*vd
= get_symbol_within_indexable (e
->base
)->referent
;
1194 for (unsigned i
= 0; i
< vars_being_iterated
.size(); ++i
)
1196 vardecl
*v
= vars_being_iterated
[i
];
1199 string err
= _F("variable '%s' modified during 'foreach' iteration",
1200 v
->name
.to_string().c_str());
1201 session
.print_error (SEMANTIC_ERROR (err
, e
->tok
));
1206 traversing_visitor::visit_arrayindex (e
);
1209 void visit_functioncall (functioncall
* e
)
1211 map
<functiondecl
*,set
<vardecl
*> *>::const_iterator i
1212 = function_mutates_vars
.find (e
->referent
);
1214 if (i
!= function_mutates_vars
.end())
1216 for (unsigned j
= 0; j
< vars_being_iterated
.size(); ++j
)
1218 vardecl
*m
= vars_being_iterated
[j
];
1219 if (i
->second
->find (m
) != i
->second
->end())
1221 string err
= _F("function call modifies var '%s' during 'foreach' iteration",
1222 m
->name
.to_string().c_str());
1223 session
.print_error (SEMANTIC_ERROR (err
, e
->tok
));
1228 traversing_visitor::visit_functioncall (e
);
1231 void visit_foreach_loop(foreach_loop
* s
)
1233 vardecl
*vd
= get_symbol_within_indexable (s
->base
)->referent
;
1236 vars_being_iterated
.push_back (vd
);
1238 traversing_visitor::visit_foreach_loop (s
);
1241 vars_being_iterated
.pop_back();
1246 // ------------------------------------------------------------------------
1248 struct stat_decl_collector
1249 : public traversing_visitor
1251 systemtap_session
& session
;
1253 stat_decl_collector(systemtap_session
& sess
)
1257 void visit_stat_op (stat_op
* e
)
1259 symbol
*sym
= get_symbol_within_expression (e
->stat
);
1260 if (session
.stat_decls
.find(sym
->name
) == session
.stat_decls
.end())
1261 session
.stat_decls
[sym
->name
] = statistic_decl();
1264 void visit_assignment (assignment
* e
)
1268 symbol
*sym
= get_symbol_within_expression (e
->left
);
1269 if (session
.stat_decls
.find(sym
->name
) == session
.stat_decls
.end())
1270 session
.stat_decls
[sym
->name
] = statistic_decl();
1273 traversing_visitor::visit_assignment(e
);
1276 void visit_hist_op (hist_op
* e
)
1278 symbol
*sym
= get_symbol_within_expression (e
->stat
);
1279 statistic_decl new_stat
;
1281 if (e
->htype
== hist_linear
)
1283 new_stat
.type
= statistic_decl::linear
;
1284 assert (e
->params
.size() == 3);
1285 new_stat
.linear_low
= e
->params
[0];
1286 new_stat
.linear_high
= e
->params
[1];
1287 new_stat
.linear_step
= e
->params
[2];
1291 assert (e
->htype
== hist_log
);
1292 new_stat
.type
= statistic_decl::logarithmic
;
1293 assert (e
->params
.size() == 0);
1296 map
<interned_string
, statistic_decl
>::iterator i
= session
.stat_decls
.find(sym
->name
);
1297 if (i
== session
.stat_decls
.end())
1298 session
.stat_decls
[sym
->name
] = new_stat
;
1301 statistic_decl
& old_stat
= i
->second
;
1302 if (!(old_stat
== new_stat
))
1304 if (old_stat
.type
== statistic_decl::none
)
1305 i
->second
= new_stat
;
1308 // FIXME: Support multiple co-declared histogram types
1309 semantic_error
se(ERR_SRC
, _F("multiple histogram types declared on '%s'",
1310 sym
->name
.to_string().c_str()), e
->tok
);
1311 session
.print_error (se
);
1320 semantic_pass_stats (systemtap_session
& sess
)
1322 stat_decl_collector
sdc(sess
);
1324 for (map
<string
,functiondecl
*>::iterator it
= sess
.functions
.begin(); it
!= sess
.functions
.end(); it
++)
1325 it
->second
->body
->visit (&sdc
);
1327 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1328 sess
.probes
[i
]->body
->visit (&sdc
);
1330 for (unsigned i
= 0; i
< sess
.globals
.size(); ++i
)
1332 vardecl
*v
= sess
.globals
[i
];
1333 if (v
->type
== pe_stats
)
1336 if (sess
.stat_decls
.find(v
->name
) == sess
.stat_decls
.end())
1338 semantic_error
se(ERR_SRC
, _F("unable to infer statistic parameters for global '%s'",
1339 v
->name
.to_string().c_str()));
1340 sess
.print_error (se
);
1345 return sess
.num_errors();
1348 // ------------------------------------------------------------------------
1350 // Enforce variable-related invariants: no modification of
1351 // a foreach()-iterated array.
1353 semantic_pass_vars (systemtap_session
& sess
)
1356 map
<functiondecl
*, set
<vardecl
*> *> fmv
;
1357 no_var_mutation_during_iteration_check
chk(sess
, fmv
);
1359 for (map
<string
,functiondecl
*>::iterator it
= sess
.functions
.begin(); it
!= sess
.functions
.end(); it
++)
1361 functiondecl
* fn
= it
->second
;
1364 set
<vardecl
*> * m
= new set
<vardecl
*>();
1365 mutated_var_collector
mc (m
);
1366 fn
->body
->visit (&mc
);
1371 for (map
<string
,functiondecl
*>::iterator it
= sess
.functions
.begin(); it
!= sess
.functions
.end(); it
++)
1373 functiondecl
* fn
= it
->second
;
1374 if (fn
->body
) fn
->body
->visit (&chk
);
1377 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1379 if (sess
.probes
[i
]->body
)
1380 sess
.probes
[i
]->body
->visit (&chk
);
1383 return sess
.num_errors();
1387 // ------------------------------------------------------------------------
1389 // Rewrite probe condition expressions into probe bodies. Tricky and
1390 // exciting business, this. This:
1392 // probe foo if (g1 || g2) { ... }
1393 // probe bar { ... g1 ++ ... }
1397 // probe foo { if (! (g1 || g2)) next; ... }
1398 // probe bar { ... g1 ++ ...;
1399 // if (g1 || g2) %{ enable_probe_foo %} else %{ disable_probe_foo %}
1402 // In other words, we perform two transformations:
1403 // (1) Inline probe condition into its body.
1404 // (2) For each probe that modifies a global var in use in any probe's
1405 // condition, re-evaluate those probes' condition at the end of that
1408 // Here, we do all of (1), and half of (2): we simply collect the dependency
1409 // info between probes, which the translator will use to emit the affected
1410 // probes' condition re-evaluation. The translator will also ensure that the
1411 // conditions are evaluated using the globals' starting values prior to any
1414 // Adds the condition expression to the front of the probe's body
1416 derived_probe_condition_inline (derived_probe
*p
)
1418 expression
* e
= p
->sole_location()->condition
;
1421 if_statement
*ifs
= new if_statement ();
1423 ifs
->thenblock
= new next_statement ();
1424 ifs
->thenblock
->tok
= e
->tok
;
1425 ifs
->elseblock
= NULL
;
1426 unary_expression
*notex
= new unary_expression ();
1428 notex
->tok
= e
->tok
;
1430 ifs
->condition
= notex
;
1431 p
->body
= new block (ifs
, p
->body
);
1435 semantic_pass_conditions (systemtap_session
& sess
)
1437 map
<derived_probe
*, set
<vardecl
*> > vars_read_in_cond
;
1438 map
<derived_probe
*, set
<vardecl
*> > vars_written_in_body
;
1440 // do a first pass through the probes to ensure safety, inline any condition,
1441 // and collect var usage
1442 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1444 derived_probe
* p
= sess
.probes
[i
];
1445 expression
* e
= p
->sole_location()->condition
;
1449 varuse_collecting_visitor
vcv_cond(sess
);
1450 e
->visit (& vcv_cond
);
1452 if (!vcv_cond
.written
.empty())
1453 sess
.print_error (SEMANTIC_ERROR (_("probe condition must not "
1454 "modify any variables"),
1456 else if (vcv_cond
.embedded_seen
)
1457 sess
.print_error (SEMANTIC_ERROR (_("probe condition must not "
1458 "include impure embedded-C"),
1461 derived_probe_condition_inline(p
);
1463 vars_read_in_cond
[p
].insert(vcv_cond
.read
.begin(),
1464 vcv_cond
.read
.end());
1467 varuse_collecting_visitor
vcv_body(sess
);
1468 p
->body
->visit (& vcv_body
);
1470 vars_written_in_body
[p
].insert(vcv_body
.written
.begin(),
1471 vcv_body
.written
.end());
1474 // do a second pass to collect affected probes
1475 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1477 derived_probe
*p
= sess
.probes
[i
];
1479 // for each variable this probe modifies...
1480 set
<vardecl
*>::const_iterator var
;
1481 for (var
= vars_written_in_body
[p
].begin();
1482 var
!= vars_written_in_body
[p
].end(); ++var
)
1484 // collect probes which could be affected
1485 for (unsigned j
= 0; j
< sess
.probes
.size(); ++j
)
1487 if (vars_read_in_cond
[sess
.probes
[j
]].count(*var
))
1489 if (!p
->probes_with_affected_conditions
.count(sess
.probes
[j
]))
1491 p
->probes_with_affected_conditions
.insert(sess
.probes
[j
]);
1492 if (sess
.verbose
> 2)
1493 clog
<< "probe " << i
<< " can affect condition of "
1494 "probe " << j
<< endl
;
1501 // PR18115: We create a begin probe which is artificially registered as
1502 // affecting every other probe. This will serve as the initializer so that
1503 // other probe types with false conditions can be skipped (or registered as
1504 // disabled) during module initialization.
1506 set
<derived_probe
*> targets
;
1507 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1508 if (!vars_read_in_cond
[sess
.probes
[i
]].empty())
1509 targets
.insert(sess
.probes
[i
]);
1511 if (!targets
.empty())
1513 stringstream
ss("probe begin {}");
1515 // no good token to choose here... let's just use the condition expression
1516 // of one of the probes as the token
1517 const token
*tok
= (*targets
.begin())->sole_location()->condition
->tok
;
1519 probe
*p
= parse_synthetic_probe(sess
, ss
, tok
);
1521 throw SEMANTIC_ERROR (_("can't create cond initializer probe"), tok
);
1523 vector
<derived_probe
*> dps
;
1524 derive_probes(sess
, p
, dps
);
1526 // there should only be one
1527 assert(dps
.size() == 1);
1529 derived_probe
* dp
= dps
[0];
1530 dp
->probes_with_affected_conditions
.insert(targets
.begin(),
1532 sess
.probes
.push_back (dp
);
1533 dp
->join_group (sess
);
1535 // no need to manually do symresolution since body is empty
1538 return sess
.num_errors();
1541 // ------------------------------------------------------------------------
1544 // Simple visitor that just goes through all embedded code blocks that
1545 // are available at the end all the optimizations to register any
1546 // relevant pragmas or other indicators found, so that session flags can
1547 // be set that can be inspected at translation time to trigger any
1548 // necessary initialization of code needed by the embedded code functions.
1550 // This is only for pragmas that don't have any other side-effect than
1551 // needing some initialization at module init time. Currently handles
1552 // /* pragma:vma */ /* pragma:unwind */ /* pragma:symbol */
1554 // /* pragma:uprobes */ is handled during the typeresolution_info pass.
1555 // /* pure */, /* unprivileged */. /* myproc-unprivileged */ and /* guru */
1556 // are handled by the varuse_collecting_visitor.
1558 struct embeddedcode_info
: public functioncall_traversing_visitor
1561 systemtap_session
& session
;
1564 embeddedcode_info (systemtap_session
& s
): session(s
) { }
1566 void visit_embeddedcode (embeddedcode
* c
)
1568 if (! vma_tracker_enabled(session
)
1569 && c
->code
.find("/* pragma:vma */") != string::npos
)
1571 if (session
.verbose
> 2)
1572 clog
<< _F("Turning on task_finder vma_tracker, pragma:vma found in %s",
1573 current_function
->name
.to_string().c_str()) << endl
;
1575 // PR15052: stapdyn doesn't have VMA-tracking yet.
1576 if (session
.runtime_usermode_p())
1577 throw SEMANTIC_ERROR(_("VMA-tracking is only supported by the kernel runtime (PR15052)"), c
->tok
);
1579 enable_vma_tracker(session
);
1582 if (! session
.need_unwind
1583 && c
->code
.find("/* pragma:unwind */") != string::npos
)
1585 if (session
.verbose
> 2)
1586 clog
<< _F("Turning on unwind support, pragma:unwind found in %s",
1587 current_function
->name
.to_string().c_str()) << endl
;
1588 session
.need_unwind
= true;
1591 if (! session
.need_symbols
1592 && c
->code
.find("/* pragma:symbols */") != string::npos
)
1594 if (session
.verbose
> 2)
1595 clog
<< _F("Turning on symbol data collecting, pragma:symbols found in %s",
1596 current_function
->name
.to_string().c_str()) << endl
;
1597 session
.need_symbols
= true;
1600 if (! session
.need_lines
1601 && c
->code
.find("/* pragma:lines */") != string::npos
)
1603 if (session
.verbose
> 2)
1604 clog
<< _F("Turning on debug line data collecting, pragma:lines found in %s",
1605 current_function
->name
.to_string().c_str()) << endl
;
1606 session
.need_lines
= true;
1611 void embeddedcode_info_pass (systemtap_session
& s
)
1613 embeddedcode_info
eci (s
);
1614 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
1615 s
.probes
[i
]->body
->visit (& eci
);
1618 // ------------------------------------------------------------------------
1621 // Simple visitor that collects all the regular expressions in the
1622 // file and adds them to the session DFA table.
1624 struct regex_collecting_visitor
: public functioncall_traversing_visitor
1627 systemtap_session
& session
;
1630 regex_collecting_visitor (systemtap_session
& s
): session(s
) { }
1632 void visit_regex_query (regex_query
*q
) {
1633 functioncall_traversing_visitor::visit_regex_query (q
);
1635 string re
= q
->right
->value
;
1636 regex_to_stapdfa (&session
, re
, q
->right
->tok
);
1640 // Go through the regex match invocations and generate corresponding DFAs.
1641 int gen_dfa_table (systemtap_session
& s
)
1643 regex_collecting_visitor
rcv(s
);
1645 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
1649 s
.probes
[i
]->body
->visit (& rcv
);
1651 if (s
.probes
[i
]->sole_location()->condition
)
1652 s
.probes
[i
]->sole_location()->condition
->visit (& rcv
);
1654 catch (const semantic_error
& e
)
1660 return s
.num_errors();
1663 // ------------------------------------------------------------------------
1666 static int semantic_pass_symbols (systemtap_session
&);
1667 static int semantic_pass_optimize1 (systemtap_session
&);
1668 static int semantic_pass_optimize2 (systemtap_session
&);
1669 static int semantic_pass_types (systemtap_session
&);
1670 static int semantic_pass_vars (systemtap_session
&);
1671 static int semantic_pass_stats (systemtap_session
&);
1672 static int semantic_pass_conditions (systemtap_session
&);
1675 struct expression_build_no_more_visitor
: public expression_visitor
1677 // Clear extra details from every expression, like DWARF type info, so that
1678 // builders can safely release them in build_no_more. From here on out,
1679 // we're back to basic types only.
1680 void visit_expression(expression
*e
)
1682 e
->type_details
.reset();
1687 build_no_more (systemtap_session
& s
)
1689 expression_build_no_more_visitor v
;
1691 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
1692 s
.probes
[i
]->body
->visit(&v
);
1694 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
1695 it
!= s
.functions
.end(); it
++)
1696 it
->second
->body
->visit(&v
);
1698 // Inform all derived_probe builders that we're done with
1699 // all resolution, so it's time to release caches.
1700 s
.pattern_root
->build_no_more (s
);
1705 // Link up symbols to their declarations. Set the session's
1706 // files/probes/functions/globals vectors from the transitively
1707 // reached set of stapfiles in s.library_files, starting from
1708 // s.user_file. Perform automatic tapset inclusion and probe
1711 semantic_pass_symbols (systemtap_session
& s
)
1713 symresolution_info
sym (s
);
1715 // If we're listing functions, then we need to include all the files. Probe
1716 // aliases won't be visited/derived so all we gain are the functions, global
1717 // variables, and any real probes (e.g. begin probes). NB: type resolution for
1718 // a specific function arg may fail if it could only be determined from a
1719 // function call in one of the skipped aliases.
1720 if (s
.dump_mode
== systemtap_session::dump_functions
)
1722 s
.files
.insert(s
.files
.end(), s
.library_files
.begin(),
1723 s
.library_files
.end());
1725 else if (!s
.user_files
.empty())
1727 // Normal run: seed s.files with user_files and let it grow through the
1728 // find_* functions. NB: s.files can grow during this iteration, so
1729 // size() can return gradually increasing numbers.
1730 s
.files
.insert (s
.files
.end(), s
.user_files
.begin(), s
.user_files
.end());
1733 for (unsigned i
= 0; i
< s
.files
.size(); i
++)
1735 assert_no_interrupts();
1736 stapfile
* dome
= s
.files
[i
];
1738 // Pass 1: add globals and functions to systemtap-session master list,
1739 // so the find_* functions find them
1741 // NB: tapset global/function definitions may duplicate or conflict
1742 // with those already in s.globals/functions. We need to deconflict
1745 for (unsigned i
=0; i
<dome
->globals
.size(); i
++)
1747 vardecl
* g
= dome
->globals
[i
];
1748 for (unsigned j
=0; j
<s
.globals
.size(); j
++)
1750 vardecl
* g2
= s
.globals
[j
];
1751 if (g
->name
== g2
->name
)
1753 s
.print_error (SEMANTIC_ERROR (_("conflicting global variables"),
1757 s
.globals
.push_back (g
);
1760 for (unsigned i
=0; i
<dome
->functions
.size(); i
++)
1762 functiondecl
* f
= dome
->functions
[i
];
1763 functiondecl
* f2
= s
.functions
[f
->name
];
1766 s
.print_error (SEMANTIC_ERROR (_("conflicting functions"),
1769 s
.functions
[f
->name
] = f
;
1772 // NB: embeds don't conflict with each other
1773 for (unsigned i
=0; i
<dome
->embeds
.size(); i
++)
1774 s
.embeds
.push_back (dome
->embeds
[i
]);
1776 // Pass 2: derive probes and resolve any further symbols in the
1779 for (unsigned i
=0; i
<dome
->probes
.size(); i
++)
1781 assert_no_interrupts();
1782 probe
* p
= dome
->probes
[i
];
1783 vector
<derived_probe
*> dps
;
1785 // much magic happens here: probe alias expansion, wildcard
1786 // matching, low-level derived_probe construction.
1787 derive_probes (s
, p
, dps
);
1789 for (unsigned j
=0; j
<dps
.size(); j
++)
1791 assert_no_interrupts();
1792 derived_probe
* dp
= dps
[j
];
1793 s
.probes
.push_back (dp
);
1798 for (unsigned k
=0; k
<s
.code_filters
.size(); k
++)
1799 s
.code_filters
[k
]->replace (dp
->body
);
1801 sym
.current_function
= 0;
1802 sym
.current_probe
= dp
;
1803 dp
->body
->visit (& sym
);
1805 // Process the probe-point condition expression.
1806 sym
.current_function
= 0;
1807 sym
.current_probe
= 0;
1808 if (dp
->sole_location()->condition
)
1809 dp
->sole_location()->condition
->visit (& sym
);
1811 catch (const semantic_error
& e
)
1818 // Pass 3: process functions
1820 for (unsigned i
=0; i
<dome
->functions
.size(); i
++)
1822 assert_no_interrupts();
1823 functiondecl
* fd
= dome
->functions
[i
];
1827 for (unsigned j
=0; j
<s
.code_filters
.size(); j
++)
1828 s
.code_filters
[j
]->replace (fd
->body
);
1830 sym
.current_function
= fd
;
1831 sym
.current_probe
= 0;
1832 fd
->body
->visit (& sym
);
1834 catch (const semantic_error
& e
)
1841 if(s
.systemtap_v_check
){
1842 for(unsigned i
=0;i
<s
.globals
.size();i
++){
1843 if(s
.globals
[i
]->systemtap_v_conditional
)
1844 s
.print_warning(_("This global uses tapset constructs that are dependent on systemtap version"), s
.globals
[i
]->tok
);
1847 for(map
<string
, functiondecl
*>::const_iterator i
=s
.functions
.begin();i
!= s
.functions
.end();++i
){
1848 if(i
->second
->systemtap_v_conditional
)
1849 s
.print_warning(_("This function uses tapset constructs that are dependent on systemtap version"), i
->second
->tok
);
1852 for(unsigned i
=0;i
<s
.probes
.size();i
++){
1853 vector
<probe
*> sysvc
;
1854 s
.probes
[i
]->collect_derivation_chain(sysvc
);
1855 for(unsigned j
=0;j
<sysvc
.size();j
++){
1856 if(sysvc
[j
]->systemtap_v_conditional
)
1857 s
.print_warning(_("This probe uses tapset constructs that are dependent on systemtap version"), sysvc
[j
]->tok
);
1858 if(sysvc
[j
]->get_alias() && sysvc
[j
]->get_alias()->systemtap_v_conditional
)
1859 s
.print_warning(_("This alias uses tapset constructs that are dependent on systemtap version"), sysvc
[j
]->get_alias()->tok
);
1864 return s
.num_errors(); // all those print_error calls
1868 // Keep unread global variables for probe end value display.
1869 void add_global_var_display (systemtap_session
& s
)
1871 // Don't generate synthetic end probes when in listing mode; it would clutter
1872 // up the list of probe points with "end ...". In fact, don't bother in any
1873 // dump mode at all, since it'll never be used.
1874 if (s
.dump_mode
) return;
1876 varuse_collecting_visitor
vut(s
);
1878 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
1880 s
.probes
[i
]->body
->visit (& vut
);
1882 if (s
.probes
[i
]->sole_location()->condition
)
1883 s
.probes
[i
]->sole_location()->condition
->visit (& vut
);
1886 for (unsigned g
=0; g
< s
.globals
.size(); g
++)
1888 vardecl
* l
= s
.globals
[g
];
1889 if ((vut
.read
.find (l
) != vut
.read
.end()
1890 && vut
.used
.find (l
) != vut
.used
.end())
1891 || vut
.written
.find (l
) == vut
.written
.end())
1894 // Don't generate synthetic end probes for unread globals
1895 // declared only within tapsets. (RHBZ 468139), but rather
1896 // only within the end-user script.
1898 bool tapset_global
= false;
1899 for (size_t m
=0; m
< s
.library_files
.size(); m
++)
1901 for (size_t n
=0; n
< s
.library_files
[m
]->globals
.size(); n
++)
1903 if (l
->name
== s
.library_files
[m
]->globals
[n
]->name
)
1904 {tapset_global
= true; break;}
1911 code
<< "probe end {" << endl
;
1913 string format
= l
->tok
->content
;
1916 string foreach_value
;
1917 if (!l
->index_types
.empty())
1919 // Add index values to the printf format, and prepare
1920 // a simple list of indexes for passing around elsewhere
1922 for (size_t i
= 0; i
< l
->index_types
.size(); ++i
)
1929 indexes
+= "__idx" + lex_cast(i
);
1930 if (l
->index_types
[i
] == pe_string
)
1931 format
+= "\\\"%#s\\\"";
1937 // Iterate over all indexes in the array, sorted by decreasing value
1938 code
<< "foreach (";
1939 if (l
->type
!= pe_stats
)
1941 foreach_value
= "__val";
1942 code
<< foreach_value
<< " = ";
1944 code
<< "[" << indexes
<< "] in " << l
->tok
->content
<< "-)" << endl
;
1946 else if (l
->type
== pe_stats
)
1948 // PR7053: Check scalar globals for empty aggregate
1949 code
<< "if (@count(" << l
->tok
->content
<< ") == 0)" << endl
;
1950 code
<< "printf(\"" << l
->tok
->content
<< " @count=0x0\\n\")" << endl
;
1951 code
<< "else" << endl
;
1954 static const string stats
[] = { "@count", "@min", "@max", "@sum", "@avg" };
1955 const string stats_format
=
1956 (strverscmp(s
.compatible
.c_str(), "1.4") >= 0) ? "%#d" : "%#x";
1958 // Fill in the printf format for values
1959 if (l
->type
== pe_stats
)
1960 for (size_t i
= 0; i
< sizeof(stats
)/sizeof(stats
[0]); ++i
)
1961 format
+= " " + stats
[i
] + "=" + stats_format
;
1962 else if (l
->type
== pe_string
)
1963 format
+= "=\\\"%#s\\\"";
1968 // Output the actual printf
1969 code
<< "printf (\"" << format
<< "\"";
1971 // Feed indexes to the printf, and include them in the value
1972 string value
= !foreach_value
.empty() ? foreach_value
: string(l
->tok
->content
);
1973 if (!l
->index_types
.empty())
1975 code
<< "," << indexes
;
1976 if (foreach_value
.empty())
1977 value
+= "[" + indexes
+ "]";
1980 // Feed the actual values to the printf
1981 if (l
->type
== pe_stats
)
1982 for (size_t i
= 0; i
< sizeof(stats
)/sizeof(stats
[0]); ++i
)
1983 code
<< "," << stats
[i
] << "(" << value
<< ")";
1985 code
<< "," << value
;
1986 code
<< ")" << endl
;
1989 code
<< "}" << endl
;
1991 probe
*p
= parse_synthetic_probe (s
, code
, l
->tok
);
1993 throw SEMANTIC_ERROR (_("can't create global var display"), l
->tok
);
1995 vector
<derived_probe
*> dps
;
1996 derive_probes (s
, p
, dps
);
1997 for (unsigned i
= 0; i
< dps
.size(); i
++)
1999 derived_probe
* dp
= dps
[i
];
2000 s
.probes
.push_back (dp
);
2003 // Repopulate symbol and type info
2004 symresolution_info
sym (s
);
2005 sym
.current_function
= 0;
2006 sym
.current_probe
= dp
;
2007 dp
->body
->visit (& sym
);
2010 semantic_pass_types(s
);
2011 // Mark that variable is read
2012 vut
.read
.insert (l
);
2017 semantic_pass (systemtap_session
& s
)
2023 s
.register_library_aliases();
2024 register_standard_tapsets(s
);
2026 if (rc
== 0) rc
= semantic_pass_symbols (s
);
2027 if (rc
== 0) rc
= semantic_pass_conditions (s
);
2028 if (rc
== 0) rc
= semantic_pass_optimize1 (s
);
2029 if (rc
== 0) rc
= semantic_pass_types (s
);
2030 if (rc
== 0) rc
= gen_dfa_table(s
);
2031 if (rc
== 0) add_global_var_display (s
);
2032 if (rc
== 0) rc
= semantic_pass_optimize2 (s
);
2033 if (rc
== 0) rc
= semantic_pass_vars (s
);
2034 if (rc
== 0) rc
= semantic_pass_stats (s
);
2035 if (rc
== 0) embeddedcode_info_pass (s
);
2037 catch (const semantic_error
& e
)
2043 bool no_primary_probes
= true;
2044 for (unsigned i
= 0; i
< s
.probes
.size(); i
++)
2045 if (s
.is_primary_probe(s
.probes
[i
]))
2046 no_primary_probes
= false;
2048 if (s
.num_errors() == 0 && no_primary_probes
&& !s
.dump_mode
)
2050 s
.print_error(SEMANTIC_ERROR(_("no probes found")));
2057 // NB: listing mode only cares whether we have any probes,
2058 // so all previous error conditions are disregarded.
2059 if (s
.dump_mode
== systemtap_session::dump_matched_probes
||
2060 s
.dump_mode
== systemtap_session::dump_matched_probes_vars
)
2061 rc
= no_primary_probes
;
2063 // If we're dumping functions, only error out if no functions were found
2064 if (s
.dump_mode
== systemtap_session::dump_functions
)
2065 rc
= s
.functions
.empty();
2071 // ------------------------------------------------------------------------
2072 // semantic processing: symbol resolution
2075 symresolution_info::symresolution_info (systemtap_session
& s
):
2076 session (s
), current_function (0), current_probe (0)
2082 symresolution_info::visit_block (block
* e
)
2084 for (unsigned i
=0; i
<e
->statements
.size(); i
++)
2088 e
->statements
[i
]->visit (this);
2090 catch (const semantic_error
& e
)
2092 session
.print_error (e
);
2099 symresolution_info::visit_foreach_loop (foreach_loop
* e
)
2101 for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
2102 e
->indexes
[i
]->visit (this);
2103 for (unsigned i
=0; i
<e
->array_slice
.size(); i
++)
2104 if (e
->array_slice
[i
])
2105 e
->array_slice
[i
]->visit(this);
2107 symbol
*array
= NULL
;
2108 hist_op
*hist
= NULL
;
2109 classify_indexable (e
->base
, array
, hist
);
2113 if (!array
->referent
)
2115 vardecl
* d
= find_var (array
->name
, e
->indexes
.size (), array
->tok
);
2118 array
->referent
= d
;
2119 array
->name
= d
->name
;
2124 msg
<< _F("unresolved arity-%zu global array %s, missing global declaration?",
2125 e
->indexes
.size(), array
->name
.to_string().c_str());
2126 throw SEMANTIC_ERROR (msg
.str(), array
->tok
);
2130 if (!e
->array_slice
.empty() && e
->array_slice
.size() != e
->indexes
.size())
2133 msg
<< _F("unresolved arity-%zu global array %s, missing global declaration?",
2134 e
->array_slice
.size(), array
->name
.to_string().c_str());
2135 throw SEMANTIC_ERROR (msg
.str(), array
->tok
);
2145 e
->value
->visit (this);
2148 e
->limit
->visit (this);
2150 e
->block
->visit (this);
2155 delete_statement_symresolution_info
:
2156 public traversing_visitor
2158 symresolution_info
*parent
;
2160 delete_statement_symresolution_info (symresolution_info
*p
):
2164 void visit_arrayindex (arrayindex
* e
)
2166 parent
->visit_arrayindex(e
, true);
2169 void visit_functioncall (functioncall
* e
)
2171 parent
->visit_functioncall (e
);
2174 void visit_symbol (symbol
* e
)
2179 vardecl
* d
= parent
->find_var (e
->name
, -1, e
->tok
);
2183 throw SEMANTIC_ERROR (_("unresolved array in delete statement"), e
->tok
);
2188 symresolution_info::visit_delete_statement (delete_statement
* s
)
2190 delete_statement_symresolution_info
di (this);
2191 s
->value
->visit (&di
);
2196 symresolution_info::visit_symbol (symbol
* e
)
2201 vardecl
* d
= find_var (e
->name
, 0, e
->tok
);
2210 vardecl
* v
= new vardecl
;
2213 v
->set_arity(0, e
->tok
);
2214 if (current_function
)
2215 current_function
->locals
.push_back (v
);
2216 else if (current_probe
)
2217 current_probe
->locals
.push_back (v
);
2219 // must be probe-condition expression
2220 throw SEMANTIC_ERROR (_("probe condition must not reference undeclared global"), e
->tok
);
2227 symresolution_info::visit_arrayindex (arrayindex
* e
)
2229 visit_arrayindex(e
, false);
2233 symresolution_info::visit_arrayindex (arrayindex
* e
, bool wildcard_ok
)
2235 for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
2237 // assuming that if NULL, it was originally a wildcard (*)
2238 if (e
->indexes
[i
] == NULL
)
2241 throw SEMANTIC_ERROR(_("wildcard not allowed in array index"), e
->tok
);
2244 e
->indexes
[i
]->visit (this);
2247 symbol
*array
= NULL
;
2248 hist_op
*hist
= NULL
;
2249 classify_indexable(e
->base
, array
, hist
);
2253 if (array
->referent
)
2256 vardecl
* d
= find_var (array
->name
, e
->indexes
.size (), array
->tok
);
2259 array
->referent
= d
;
2260 array
->name
= d
->name
;
2265 msg
<< _F("unresolved arity-%zu global array %s, missing global declaration?",
2266 e
->indexes
.size(), array
->name
.to_string().c_str());
2267 throw SEMANTIC_ERROR (msg
.str(), e
->tok
);
2279 symresolution_info::visit_array_in (array_in
* e
)
2281 visit_arrayindex(e
->operand
, true);
2286 symresolution_info::visit_functioncall (functioncall
* e
)
2288 // XXX: we could relax this, if we're going to examine the
2289 // vartracking data recursively. See testsuite/semko/fortytwo.stp.
2290 if (! (current_function
|| current_probe
))
2292 // must be probe-condition expression
2293 throw SEMANTIC_ERROR (_("probe condition must not reference function"), e
->tok
);
2296 for (unsigned i
=0; i
<e
->args
.size(); i
++)
2297 e
->args
[i
]->visit (this);
2302 functiondecl
* d
= find_function (e
->function
, e
->args
.size (), e
->tok
);
2306 e
->function
= d
->name
;
2310 string sugs
= levenshtein_suggest(e
->function
, collect_functions(), 5); // print 5 funcs
2311 throw SEMANTIC_ERROR(_F("unresolved function%s",
2312 sugs
.empty() ? "" : (_(" (similar: ") + sugs
+ ")").c_str()),
2317 /*find_var will return an argument other than zero if the name matches the var
2318 * name ie, if the current local name matches the name passed to find_var*/
2320 symresolution_info::find_var (interned_string name
, int arity
, const token
* tok
)
2322 if (current_function
|| current_probe
)
2325 vector
<vardecl
*>& locals
= (current_function
?
2326 current_function
->locals
:
2327 current_probe
->locals
);
2330 for (unsigned i
=0; i
<locals
.size(); i
++)
2331 if (locals
[i
]->name
== name
)
2333 locals
[i
]->set_arity (arity
, tok
);
2338 // search function formal parameters (for scalars)
2339 if (arity
== 0 && current_function
)
2340 for (unsigned i
=0; i
<current_function
->formal_args
.size(); i
++)
2341 if (current_function
->formal_args
[i
]->name
== name
)
2343 // NB: no need to check arity here: formal args always scalar
2344 current_function
->formal_args
[i
]->set_arity (0, tok
);
2345 return current_function
->formal_args
[i
];
2348 // search processed globals
2349 string gname
= "__global_" + string(name
);
2350 string pname
= "__private_" + detox_path(tok
->location
.file
->name
) + string(name
);
2351 for (unsigned i
=0; i
<session
.globals
.size(); i
++)
2353 if ((session
.globals
[i
]->name
== name
&& startswith(name
, "__global_")) ||
2354 (session
.globals
[i
]->name
== gname
) ||
2355 (session
.globals
[i
]->name
== pname
))
2357 if (! session
.suppress_warnings
)
2359 vardecl
* v
= session
.globals
[i
];
2360 stapfile
* f
= tok
->location
.file
;
2361 // clog << "resolved " << *tok << " to global " << *v->tok << endl;
2362 if (v
->tok
->location
.file
!= f
&& !f
->synthetic
)
2364 session
.print_warning (_F("cross-file global variable reference to %s from",
2365 lex_cast(*v
->tok
).c_str()), tok
);
2368 session
.globals
[i
]->set_arity (arity
, tok
);
2369 return session
.globals
[i
];
2373 // search library globals
2374 for (unsigned i
=0; i
<session
.library_files
.size(); i
++)
2376 stapfile
* f
= session
.library_files
[i
];
2377 for (unsigned j
=0; j
<f
->globals
.size(); j
++)
2379 vardecl
* g
= f
->globals
[j
];
2380 if (g
->name
== gname
)
2382 g
->set_arity (arity
, tok
);
2384 // put library into the queue if not already there
2385 if (find (session
.files
.begin(), session
.files
.end(), f
)
2386 == session
.files
.end())
2387 session
.files
.push_back (f
);
2399 symresolution_info::find_function (const string
& name
, unsigned arity
, const token
*tok
)
2401 string gname
= "__global_" + string(name
);
2402 string pname
= "__private_" + detox_path(tok
->location
.file
->name
) + string(name
);
2406 // internal global functions bypassing the parser, such as __global_dwarf_tvar_[gs]et
2407 if ((session
.functions
.find(name
) != session
.functions
.end()) && startswith(name
, "__private_"))
2409 functiondecl
* fd
= session
.functions
[name
];
2410 assert (fd
->name
== name
);
2411 if (fd
->formal_args
.size() == arity
)
2414 throw SEMANTIC_ERROR(_F("arity mismatch found (function '%s' takes %zu args)",
2415 name
.c_str(), fd
->formal_args
.size()), tok
, fd
->tok
);
2418 // tapset or user script global functions coming from the parser
2419 if (session
.functions
.find(gname
) != session
.functions
.end())
2421 functiondecl
* fd
= session
.functions
[gname
];
2422 assert (fd
->name
== gname
);
2423 if (fd
->formal_args
.size() == arity
)
2426 throw SEMANTIC_ERROR(_F("arity mismatch found (function '%s' takes %zu args)",
2427 name
.c_str(), fd
->formal_args
.size()), tok
, fd
->tok
);
2430 // tapset or user script private functions coming from the parser
2431 if (session
.functions
.find(pname
) != session
.functions
.end())
2433 functiondecl
* fd
= session
.functions
[pname
];
2434 assert (fd
->name
== pname
);
2435 if (fd
->formal_args
.size() == arity
)
2438 throw SEMANTIC_ERROR(_F("arity mismatch found (function '%s' takes %zu args)",
2439 name
.c_str(), fd
->formal_args
.size()), tok
, fd
->tok
);
2442 // search library functions
2443 for (unsigned i
=0; i
<session
.library_files
.size(); i
++)
2445 stapfile
* f
= session
.library_files
[i
];
2446 for (unsigned j
=0; j
<f
->functions
.size(); j
++)
2448 if ((f
->functions
[j
]->name
== gname
) ||
2449 (f
->functions
[j
]->name
== pname
))
2451 if (f
->functions
[j
]->formal_args
.size() == arity
)
2453 // put library into the queue if not already there
2454 if (0) // session.verbose_resolution
2455 cerr
<< _F(" function %s is defined from %s",
2456 name
.c_str(), f
->name
.c_str()) << endl
;
2458 if (find (session
.files
.begin(), session
.files
.end(), f
)
2459 == session
.files
.end())
2460 session
.files
.push_back (f
);
2461 // else .. print different message?
2463 return f
->functions
[j
];
2466 throw SEMANTIC_ERROR(_F("arity mismatch found (function '%s' takes %zu args)",
2467 name
.c_str(), f
->functions
[j
]->formal_args
.size()),
2468 tok
, f
->functions
[j
]->tok
);
2477 symresolution_info::collect_functions(void)
2481 for (map
<string
,functiondecl
*>::const_iterator it
= session
.functions
.begin();
2482 it
!= session
.functions
.end(); ++it
)
2483 funcs
.insert(it
->first
);
2485 // search library functions
2486 for (unsigned i
=0; i
<session
.library_files
.size(); i
++)
2488 stapfile
* f
= session
.library_files
[i
];
2489 for (unsigned j
=0; j
<f
->functions
.size(); j
++)
2490 funcs
.insert(f
->functions
[j
]->name
);
2496 // ------------------------------------------------------------------------
2500 // Do away with functiondecls that are never (transitively) called
2502 void semantic_pass_opt1 (systemtap_session
& s
, bool& relaxed_p
)
2504 functioncall_traversing_visitor ftv
;
2505 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
2507 s
.probes
[i
]->body
->visit (& ftv
);
2508 if (s
.probes
[i
]->sole_location()->condition
)
2509 s
.probes
[i
]->sole_location()->condition
->visit (& ftv
);
2511 vector
<functiondecl
*> new_unused_functions
;
2512 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
2514 functiondecl
* fd
= it
->second
;
2515 if (ftv
.seen
.find(fd
) == ftv
.seen
.end())
2517 if (! fd
->synthetic
&& s
.is_user_file(fd
->tok
->location
.file
->name
))
2518 s
.print_warning (_F("Eliding unused function '%s'",
2519 fd
->name
.to_string().c_str()), fd
->tok
);
2520 // s.functions.erase (it); // NB: can't, since we're already iterating upon it
2521 new_unused_functions
.push_back (fd
);
2525 for (unsigned i
=0; i
<new_unused_functions
.size(); i
++)
2527 map
<string
,functiondecl
*>::iterator where
= s
.functions
.find (new_unused_functions
[i
]->name
);
2528 assert (where
!= s
.functions
.end());
2529 s
.functions
.erase (where
);
2530 if (s
.tapset_compile_coverage
)
2531 s
.unused_functions
.push_back (new_unused_functions
[i
]);
2536 // ------------------------------------------------------------------------
2538 // Do away with local & global variables that are never
2539 // written nor read.
2540 void semantic_pass_opt2 (systemtap_session
& s
, bool& relaxed_p
, unsigned iterations
)
2542 varuse_collecting_visitor
vut(s
);
2544 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
2546 s
.probes
[i
]->body
->visit (& vut
);
2548 if (s
.probes
[i
]->sole_location()->condition
)
2549 s
.probes
[i
]->sole_location()->condition
->visit (& vut
);
2552 // NB: Since varuse_collecting_visitor also traverses down
2553 // actually called functions, we don't need to explicitly
2554 // iterate over them. Uncalled ones should have been pruned
2557 // for (unsigned i=0; i<s.functions.size(); i++)
2558 // s.functions[i]->body->visit (& vut);
2560 // Now in vut.read/written, we have a mixture of all locals, globals
2562 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
2563 for (unsigned j
=0; j
<s
.probes
[i
]->locals
.size(); /* see below */)
2565 vardecl
* l
= s
.probes
[i
]->locals
[j
];
2567 // skip over "special" locals
2568 if (l
->synthetic
) { j
++; continue; }
2570 if (vut
.read
.find (l
) == vut
.read
.end() &&
2571 vut
.written
.find (l
) == vut
.written
.end())
2573 if (s
.is_user_file(l
->tok
->location
.file
->name
))
2574 s
.print_warning (_F("Eliding unused variable '%s'",
2575 l
->name
.to_string().c_str()), l
->tok
);
2576 if (s
.tapset_compile_coverage
) {
2577 s
.probes
[i
]->unused_locals
.push_back
2578 (s
.probes
[i
]->locals
[j
]);
2580 s
.probes
[i
]->locals
.erase(s
.probes
[i
]->locals
.begin() + j
);
2582 // don't increment j
2586 if (vut
.written
.find (l
) == vut
.written
.end())
2587 if (iterations
== 0 && ! s
.suppress_warnings
)
2590 vector
<vardecl
*>::iterator it
;
2591 for (it
= s
.probes
[i
]->locals
.begin(); it
!= s
.probes
[i
]->locals
.end(); it
++)
2592 vars
.insert((*it
)->name
);
2593 for (it
= s
.globals
.begin(); it
!= s
.globals
.end(); it
++)
2594 vars
.insert((*it
)->name
);
2596 vars
.erase(l
->name
);
2597 string sugs
= levenshtein_suggest(l
->name
, vars
, 5); // suggest top 5 vars
2598 s
.print_warning (_F("never-assigned local variable '%s'%s",
2599 l
->name
.to_string().c_str(), (sugs
.empty() ? "" :
2600 (_(" (similar: ") + sugs
+ ")")).c_str()), l
->tok
);
2606 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
2608 functiondecl
*fd
= it
->second
;
2609 for (unsigned j
=0; j
<fd
->locals
.size(); /* see below */)
2611 vardecl
* l
= fd
->locals
[j
];
2612 if (vut
.read
.find (l
) == vut
.read
.end() &&
2613 vut
.written
.find (l
) == vut
.written
.end())
2615 if (s
.is_user_file(l
->tok
->location
.file
->name
))
2616 s
.print_warning (_F("Eliding unused variable '%s'",
2617 l
->name
.to_string().c_str()), l
->tok
);
2618 if (s
.tapset_compile_coverage
) {
2619 fd
->unused_locals
.push_back (fd
->locals
[j
]);
2621 fd
->locals
.erase(fd
->locals
.begin() + j
);
2623 // don't increment j
2627 if (vut
.written
.find (l
) == vut
.written
.end())
2628 if (iterations
== 0 && ! s
.suppress_warnings
)
2631 vector
<vardecl
*>::iterator it
;
2632 for (it
= fd
->formal_args
.begin() ;
2633 it
!= fd
->formal_args
.end(); it
++)
2634 vars
.insert((*it
)->name
);
2635 for (it
= fd
->locals
.begin(); it
!= fd
->locals
.end(); it
++)
2636 vars
.insert((*it
)->name
);
2637 for (it
= s
.globals
.begin(); it
!= s
.globals
.end(); it
++)
2638 vars
.insert((*it
)->name
);
2640 vars
.erase(l
->name
);
2641 string sugs
= levenshtein_suggest(l
->name
, vars
, 5); // suggest top 5 vars
2642 s
.print_warning (_F("never-assigned local variable '%s'%s",
2643 l
->name
.to_string().c_str(), (sugs
.empty() ? "" :
2644 (_(" (similar: ") + sugs
+ ")")).c_str()), l
->tok
);
2651 for (unsigned i
=0; i
<s
.globals
.size(); /* see below */)
2653 vardecl
* l
= s
.globals
[i
];
2654 if (vut
.read
.find (l
) == vut
.read
.end() &&
2655 vut
.written
.find (l
) == vut
.written
.end())
2657 if (s
.is_user_file(l
->tok
->location
.file
->name
))
2658 s
.print_warning (_F("Eliding unused variable '%s'",
2659 l
->name
.to_string().c_str()), l
->tok
);
2660 if (s
.tapset_compile_coverage
) {
2661 s
.unused_globals
.push_back(s
.globals
[i
]);
2663 s
.globals
.erase(s
.globals
.begin() + i
);
2665 // don't increment i
2669 if (vut
.written
.find (l
) == vut
.written
.end() && ! l
->init
) // no initializer
2670 if (iterations
== 0 && ! s
.suppress_warnings
)
2673 vector
<vardecl
*>::iterator it
;
2674 for (it
= s
.globals
.begin(); it
!= s
.globals
.end(); it
++)
2675 if (l
->name
!= (*it
)->name
)
2676 vars
.insert((*it
)->name
);
2678 string sugs
= levenshtein_suggest(l
->name
, vars
, 5); // suggest top 5 vars
2679 s
.print_warning (_F("never-assigned global variable '%s'%s",
2680 l
->name
.to_string().c_str(), (sugs
.empty() ? "" :
2681 (_(" (similar: ") + sugs
+ ")")).c_str()), l
->tok
);
2690 // ------------------------------------------------------------------------
2692 struct dead_assignment_remover
: public update_visitor
2694 systemtap_session
& session
;
2696 const varuse_collecting_visitor
& vut
;
2698 dead_assignment_remover(systemtap_session
& s
, bool& r
,
2699 const varuse_collecting_visitor
& v
):
2700 session(s
), relaxed_p(r
), vut(v
) {}
2702 void visit_assignment (assignment
* e
);
2703 void visit_try_block (try_block
*s
);
2707 // symbol_fetcher augmented to allow target-symbol types, but NULLed.
2708 struct assignment_symbol_fetcher
2709 : public symbol_fetcher
2711 assignment_symbol_fetcher (symbol
*&sym
): symbol_fetcher(sym
)
2714 void visit_target_symbol (target_symbol
* e
)
2719 void visit_atvar_op (atvar_op
*e
)
2724 void visit_cast_op (cast_op
* e
)
2729 void visit_autocast_op (autocast_op
* e
)
2734 void throwone (const token
* t
)
2736 if (t
->type
== tok_operator
&& t
->content
== ".")
2737 // guess someone misused . in $foo->bar.baz expression
2738 // XXX why are we only checking this in lvalues?
2739 throw SEMANTIC_ERROR (_("Expecting lvalue expression, try -> instead"), t
);
2741 throw SEMANTIC_ERROR (_("Expecting lvalue expression"), t
);
2746 get_assignment_symbol_within_expression (expression
*e
)
2749 assignment_symbol_fetcher
fetcher(sym
);
2750 e
->visit (&fetcher
);
2751 return sym
; // NB: may be null!
2756 dead_assignment_remover::visit_assignment (assignment
* e
)
2761 symbol
* left
= get_assignment_symbol_within_expression (e
->left
);
2762 if (left
) // not unresolved $target, so intended sideeffect may be elided
2764 vardecl
* leftvar
= left
->referent
;
2765 if (vut
.read
.find(leftvar
) == vut
.read
.end()) // var never read?
2767 // NB: Not so fast! The left side could be an array whose
2768 // index expressions may have side-effects. This would be
2769 // OK if we could replace the array assignment with a
2770 // statement-expression containing all the index expressions
2771 // and the rvalue... but we can't.
2772 // Another possibility is that we have an unread global variable
2773 // which are kept for probe end value display.
2775 bool is_global
= false;
2776 vector
<vardecl
*>::iterator it
;
2777 for (it
= session
.globals
.begin(); it
!= session
.globals
.end(); it
++)
2778 if (leftvar
->name
== (*it
)->name
)
2784 varuse_collecting_visitor
lvut(session
);
2785 e
->left
->visit (& lvut
);
2786 if (lvut
.side_effect_free () && !is_global
// XXX: use _wrt() once we track focal_vars
2787 && !leftvar
->synthetic
) // don't elide assignment to synthetic $context variables
2789 /* PR 1119: NB: This is not necessary here. A write-only
2790 variable will also be elided soon at the next _opt2 iteration.
2791 if (e->left->tok->location.file->name == session.user_file->name) // !tapset
2792 session.print_warning("eliding write-only ", *e->left->tok);
2795 if (session
.is_user_file(e
->left
->tok
->location
.file
->name
))
2796 session
.print_warning(_F("Eliding assignment to '%s'",
2797 leftvar
->name
.to_string().c_str()), e
->tok
);
2798 provide (e
->right
); // goodbye assignment*
2809 dead_assignment_remover::visit_try_block (try_block
*s
)
2811 replace (s
->try_block
);
2812 if (s
->catch_error_var
)
2814 vardecl
* errvar
= s
->catch_error_var
->referent
;
2815 if (vut
.read
.find(errvar
) == vut
.read
.end()) // never read?
2817 if (session
.verbose
>2)
2818 clog
<< _F("Eliding unused error string catcher %s at %s",
2819 errvar
->name
.to_string().c_str(), lex_cast(*s
->tok
).c_str()) << endl
;
2820 s
->catch_error_var
= 0;
2823 replace (s
->catch_block
);
2828 // Let's remove assignments to variables that are never read. We
2829 // rewrite "(foo = expr)" as "(expr)". This makes foo a candidate to
2830 // be optimized away as an unused variable, and expr a candidate to be
2831 // removed as a side-effect-free statement expression. Wahoo!
2832 void semantic_pass_opt3 (systemtap_session
& s
, bool& relaxed_p
)
2834 // Recompute the varuse data, which will probably match the opt2
2835 // copy of the computation, except for those totally unused
2836 // variables that opt2 removed.
2837 varuse_collecting_visitor
vut(s
);
2838 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
2839 s
.probes
[i
]->body
->visit (& vut
); // includes reachable functions too
2841 dead_assignment_remover
dar (s
, relaxed_p
, vut
);
2842 // This instance may be reused for multiple probe/function body trims.
2844 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
2845 dar
.replace (s
.probes
[i
]->body
);
2846 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
2847 it
!= s
.functions
.end(); it
++)
2848 dar
.replace (it
->second
->body
);
2849 // The rewrite operation is performed within the visitor.
2851 // XXX: we could also zap write-only globals here
2855 // ------------------------------------------------------------------------
2857 struct dead_stmtexpr_remover
: public update_visitor
2859 systemtap_session
& session
;
2861 set
<vardecl
*> focal_vars
; // vars considered subject to side-effects
2863 dead_stmtexpr_remover(systemtap_session
& s
, bool& r
):
2864 session(s
), relaxed_p(r
) {}
2866 void visit_block (block
*s
);
2867 void visit_try_block (try_block
*s
);
2868 void visit_null_statement (null_statement
*s
);
2869 void visit_if_statement (if_statement
* s
);
2870 void visit_foreach_loop (foreach_loop
*s
);
2871 void visit_for_loop (for_loop
*s
);
2872 // XXX: and other places where stmt_expr's might be nested
2874 void visit_expr_statement (expr_statement
*s
);
2879 dead_stmtexpr_remover::visit_null_statement (null_statement
*s
)
2882 if (session
.verbose
>2)
2883 clog
<< _("Eliding side-effect-free null statement ") << *s
->tok
<< endl
;
2890 dead_stmtexpr_remover::visit_block (block
*s
)
2892 vector
<statement
*> new_stmts
;
2893 for (unsigned i
=0; i
<s
->statements
.size(); i
++ )
2895 statement
* new_stmt
= require (s
->statements
[i
], true);
2898 // flatten nested blocks into this one
2899 block
*b
= dynamic_cast<block
*>(new_stmt
);
2902 if (session
.verbose
>2)
2903 clog
<< _("Flattening nested block ") << *b
->tok
<< endl
;
2904 new_stmts
.insert(new_stmts
.end(),
2905 b
->statements
.begin(), b
->statements
.end());
2909 new_stmts
.push_back (new_stmt
);
2912 if (new_stmts
.size() == 0)
2914 if (session
.verbose
>2)
2915 clog
<< _("Eliding side-effect-free empty block ") << *s
->tok
<< endl
;
2918 else if (new_stmts
.size() == 1)
2920 if (session
.verbose
>2)
2921 clog
<< _("Eliding side-effect-free singleton block ") << *s
->tok
<< endl
;
2922 provide (new_stmts
[0]);
2926 s
->statements
= new_stmts
;
2932 dead_stmtexpr_remover::visit_try_block (try_block
*s
)
2934 replace (s
->try_block
, true);
2935 replace (s
->catch_block
, true); // null catch{} is ok and useful
2936 if (s
->try_block
== 0)
2938 if (session
.verbose
>2)
2939 clog
<< _("Eliding empty try {} block ") << *s
->tok
<< endl
;
2947 dead_stmtexpr_remover::visit_if_statement (if_statement
*s
)
2949 replace (s
->thenblock
, true);
2950 replace (s
->elseblock
, true);
2952 if (s
->thenblock
== 0)
2954 if (s
->elseblock
== 0)
2956 // We may be able to elide this statement, if the condition
2957 // expression is side-effect-free.
2958 varuse_collecting_visitor
vct(session
);
2959 s
->condition
->visit(& vct
);
2960 if (vct
.side_effect_free ())
2962 if (session
.verbose
>2)
2963 clog
<< _("Eliding side-effect-free if statement ")
2965 s
= 0; // yeah, baby
2969 // We can still turn it into a simple expr_statement though...
2970 if (session
.verbose
>2)
2971 clog
<< _("Creating simple evaluation from if statement ")
2973 expr_statement
*es
= new expr_statement
;
2974 es
->value
= s
->condition
;
2975 es
->tok
= es
->value
->tok
;
2982 // For an else without a then, we can invert the condition logic to
2983 // avoid having a null statement in the thenblock
2984 if (session
.verbose
>2)
2985 clog
<< _("Inverting the condition of if statement ")
2987 unary_expression
*ue
= new unary_expression
;
2988 ue
->operand
= s
->condition
;
2989 ue
->tok
= ue
->operand
->tok
;
2992 s
->thenblock
= s
->elseblock
;
3000 dead_stmtexpr_remover::visit_foreach_loop (foreach_loop
*s
)
3002 replace (s
->block
, true);
3006 // XXX what if s->limit has side effects?
3007 // XXX what about s->indexes or s->value used outside the loop?
3008 if(session
.verbose
> 2)
3009 clog
<< _("Eliding side-effect-free foreach statement ") << *s
->tok
<< endl
;
3010 s
= 0; // yeah, baby
3016 dead_stmtexpr_remover::visit_for_loop (for_loop
*s
)
3018 replace (s
->block
, true);
3022 // We may be able to elide this statement, if the condition
3023 // expression is side-effect-free.
3024 varuse_collecting_visitor
vct(session
);
3025 if (s
->init
) s
->init
->visit(& vct
);
3026 s
->cond
->visit(& vct
);
3027 if (s
->incr
) s
->incr
->visit(& vct
);
3028 if (vct
.side_effect_free ())
3030 if (session
.verbose
>2)
3031 clog
<< _("Eliding side-effect-free for statement ") << *s
->tok
<< endl
;
3032 s
= 0; // yeah, baby
3036 // Can't elide this whole statement; put a null in there.
3037 s
->block
= new null_statement(s
->tok
);
3046 dead_stmtexpr_remover::visit_expr_statement (expr_statement
*s
)
3048 // Run a varuse query against the operand expression. If it has no
3049 // side-effects, replace the entire statement expression by a null
3050 // statement with the provide() call.
3052 // Unlike many other visitors, we do *not* traverse this outermost
3053 // one into the expression subtrees. There is no need - no
3054 // expr_statement nodes will be found there. (Function bodies
3055 // need to be visited explicitly by our caller.)
3057 // NB. While we don't share nodes in the parse tree, let's not
3058 // deallocate *s anyway, just in case...
3060 varuse_collecting_visitor
vut(session
);
3061 s
->value
->visit (& vut
);
3063 if (vut
.side_effect_free_wrt (focal_vars
))
3065 /* PR 1119: NB: this message is not a good idea here. It can
3066 name some arbitrary RHS expression of an assignment.
3067 if (s->value->tok->location.file->name == session.user_file->name) // not tapset
3068 session.print_warning("eliding never-assigned ", *s->value->tok);
3071 if (session
.is_user_file(s
->value
->tok
->location
.file
->name
))
3072 session
.print_warning("Eliding side-effect-free expression ", s
->tok
);
3074 // NB: this 0 pointer is invalid to leave around for any length of
3075 // time, but the parent parse tree objects above handle it.
3083 void semantic_pass_opt4 (systemtap_session
& s
, bool& relaxed_p
)
3085 // Finally, let's remove some statement-expressions that have no
3086 // side-effect. These should be exactly those whose private varuse
3087 // visitors come back with an empty "written" and "embedded" lists.
3089 dead_stmtexpr_remover
duv (s
, relaxed_p
);
3090 // This instance may be reused for multiple probe/function body trims.
3092 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
3094 assert_no_interrupts();
3096 derived_probe
* p
= s
.probes
[i
];
3098 duv
.focal_vars
.clear ();
3099 duv
.focal_vars
.insert (s
.globals
.begin(),
3101 duv
.focal_vars
.insert (p
->locals
.begin(),
3104 duv
.replace (p
->body
, true);
3107 if (! s
.timing
&& // PR10070
3108 !(p
->base
->tok
->location
.file
->synthetic
)) // don't warn for synthetic probes
3109 s
.print_warning (_F("side-effect-free probe '%s'",
3110 p
->name
.to_string().c_str()), p
->tok
);
3112 p
->body
= new null_statement(p
->tok
);
3114 // XXX: possible duplicate warnings; see below
3117 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
3119 assert_no_interrupts();
3121 functiondecl
* fn
= it
->second
;
3122 duv
.focal_vars
.clear ();
3123 duv
.focal_vars
.insert (fn
->locals
.begin(),
3125 duv
.focal_vars
.insert (fn
->formal_args
.begin(),
3126 fn
->formal_args
.end());
3127 duv
.focal_vars
.insert (s
.globals
.begin(),
3130 duv
.replace (fn
->body
, true);
3133 s
.print_warning (_F("side-effect-free function '%s'",
3134 fn
->name
.to_string().c_str()), fn
->tok
);
3136 fn
->body
= new null_statement(fn
->tok
);
3138 // XXX: the next iteration of the outer optimization loop may
3139 // take this new null_statement away again, and thus give us a
3140 // fresh warning. It would be better if this fixup was performed
3141 // only after the relaxation iterations.
3142 // XXX: or else see bug #6469.
3148 // ------------------------------------------------------------------------
3150 // The goal of this visitor is to reduce top-level expressions in void context
3151 // into separate statements that evaluate each subcomponent of the expression.
3152 // The dead-statement-remover can later remove some parts if they have no side
3155 // All expressions must be overridden here so we never visit their subexpressions
3156 // accidentally. Thus, the only visited expressions should be value of an
3159 // For an expression to replace its expr_statement with something else, it will
3160 // let the new statement provide(), and then provide(0) for itself. The
3161 // expr_statement will take this as a sign that it's been replaced.
3162 struct void_statement_reducer
: public update_visitor
3164 systemtap_session
& session
;
3166 set
<vardecl
*> focal_vars
; // vars considered subject to side-effects
3168 void_statement_reducer(systemtap_session
& s
, bool& r
):
3169 session(s
), relaxed_p(r
) {}
3171 void visit_expr_statement (expr_statement
* s
);
3173 // expressions in conditional / loop controls are definitely a side effect,
3174 // but still recurse into the child statements
3175 void visit_if_statement (if_statement
* s
);
3176 void visit_for_loop (for_loop
* s
);
3177 void visit_foreach_loop (foreach_loop
* s
);
3179 // these expressions get rewritten into their statement equivalents
3180 void visit_logical_or_expr (logical_or_expr
* e
);
3181 void visit_logical_and_expr (logical_and_expr
* e
);
3182 void visit_ternary_expression (ternary_expression
* e
);
3184 // all of these can (usually) be reduced into simpler statements
3185 void visit_binary_expression (binary_expression
* e
);
3186 void visit_unary_expression (unary_expression
* e
);
3187 void visit_regex_query (regex_query
* e
); // XXX depends on subexpr extraction
3188 void visit_comparison (comparison
* e
);
3189 void visit_concatenation (concatenation
* e
);
3190 void visit_functioncall (functioncall
* e
);
3191 void visit_print_format (print_format
* e
);
3192 void visit_target_symbol (target_symbol
* e
);
3193 void visit_atvar_op (atvar_op
* e
);
3194 void visit_cast_op (cast_op
* e
);
3195 void visit_autocast_op (autocast_op
* e
);
3196 void visit_defined_op (defined_op
* e
);
3198 // these are a bit hairy to grok due to the intricacies of indexables and
3199 // stats, so I'm chickening out and skipping them...
3200 void visit_array_in (array_in
* e
) { provide (e
); }
3201 void visit_arrayindex (arrayindex
* e
) { provide (e
); }
3202 void visit_stat_op (stat_op
* e
) { provide (e
); }
3203 void visit_hist_op (hist_op
* e
) { provide (e
); }
3205 // these can't be reduced because they always have an effect
3206 void visit_return_statement (return_statement
* s
) { provide (s
); }
3207 void visit_delete_statement (delete_statement
* s
) { provide (s
); }
3208 void visit_pre_crement (pre_crement
* e
) { provide (e
); }
3209 void visit_post_crement (post_crement
* e
) { provide (e
); }
3210 void visit_assignment (assignment
* e
) { provide (e
); }
3213 void reduce_target_symbol (target_symbol
* e
, expression
* operand
=NULL
);
3218 void_statement_reducer::visit_expr_statement (expr_statement
* s
)
3220 replace (s
->value
, true);
3222 // if the expression provides 0, that's our signal that a new
3223 // statement has been provided, so we shouldn't provide this one.
3229 void_statement_reducer::visit_if_statement (if_statement
* s
)
3231 // s->condition is never void
3232 replace (s
->thenblock
);
3233 replace (s
->elseblock
);
3238 void_statement_reducer::visit_for_loop (for_loop
* s
)
3240 // s->init/cond/incr are never void
3246 void_statement_reducer::visit_foreach_loop (foreach_loop
* s
)
3248 // s->indexes/base/value/limit are never void
3254 void_statement_reducer::visit_logical_or_expr (logical_or_expr
* e
)
3256 // In void context, the evaluation of "a || b" is exactly like
3257 // "if (!a) b", so let's do that instead.
3259 if (session
.verbose
>2)
3260 clog
<< _("Creating if statement from unused logical-or ")
3263 if_statement
*is
= new if_statement
;
3267 unary_expression
*ue
= new unary_expression
;
3268 ue
->operand
= e
->left
;
3273 expr_statement
*es
= new expr_statement
;
3274 es
->value
= e
->right
;
3275 es
->tok
= es
->value
->tok
;
3285 void_statement_reducer::visit_logical_and_expr (logical_and_expr
* e
)
3287 // In void context, the evaluation of "a && b" is exactly like
3288 // "if (a) b", so let's do that instead.
3290 if (session
.verbose
>2)
3291 clog
<< _("Creating if statement from unused logical-and ")
3294 if_statement
*is
= new if_statement
;
3297 is
->condition
= e
->left
;
3299 expr_statement
*es
= new expr_statement
;
3300 es
->value
= e
->right
;
3301 es
->tok
= es
->value
->tok
;
3311 void_statement_reducer::visit_ternary_expression (ternary_expression
* e
)
3313 // In void context, the evaluation of "a ? b : c" is exactly like
3314 // "if (a) b else c", so let's do that instead.
3316 if (session
.verbose
>2)
3317 clog
<< _("Creating if statement from unused ternary expression ")
3320 if_statement
*is
= new if_statement
;
3322 is
->condition
= e
->cond
;
3324 expr_statement
*es
= new expr_statement
;
3325 es
->value
= e
->truevalue
;
3326 es
->tok
= es
->value
->tok
;
3329 es
= new expr_statement
;
3330 es
->value
= e
->falsevalue
;
3331 es
->tok
= es
->value
->tok
;
3341 void_statement_reducer::visit_binary_expression (binary_expression
* e
)
3343 // When the result of a binary operation isn't needed, it's just as good to
3344 // evaluate the operands as sequential statements in a block.
3346 if (session
.verbose
>2)
3347 clog
<< _("Eliding unused binary ") << *e
->tok
<< endl
;
3349 block
*b
= new block
;
3352 expr_statement
*es
= new expr_statement
;
3353 es
->value
= e
->left
;
3354 es
->tok
= es
->value
->tok
;
3355 b
->statements
.push_back(es
);
3357 es
= new expr_statement
;
3358 es
->value
= e
->right
;
3359 es
->tok
= es
->value
->tok
;
3360 b
->statements
.push_back(es
);
3369 void_statement_reducer::visit_unary_expression (unary_expression
* e
)
3371 // When the result of a unary operation isn't needed, it's just as good to
3372 // evaluate the operand directly
3374 if (session
.verbose
>2)
3375 clog
<< _("Eliding unused unary ") << *e
->tok
<< endl
;
3378 e
->operand
->visit(this);
3382 void_statement_reducer::visit_regex_query (regex_query
* e
)
3384 // TODOXXX After subexpression extraction is implemented,
3385 // regular expression matches *may* have side-effects in
3386 // terms of producing matched subexpressions, e.g.:
3388 // str =~ "pat"; println(matched(0));
3390 // It's debatable if we want to actually allow this, though.
3392 // Treat e as a unary expression on the left operand -- since the
3393 // right hand side must be a literal (as verified by the parser),
3394 // evaluating it never has side effects.
3396 if (session
.verbose
>2)
3397 clog
<< _("Eliding regex query ") << *e
->tok
<< endl
;
3400 e
->left
->visit(this);
3404 void_statement_reducer::visit_comparison (comparison
* e
)
3406 visit_binary_expression(e
);
3410 void_statement_reducer::visit_concatenation (concatenation
* e
)
3412 visit_binary_expression(e
);
3416 void_statement_reducer::visit_functioncall (functioncall
* e
)
3418 // If a function call is pure and its result ignored, we can elide the call
3419 // and just evaluate the arguments in sequence
3421 if (!e
->args
.size())
3427 varuse_collecting_visitor
vut(session
);
3428 vut
.seen
.insert (e
->referent
);
3429 vut
.current_function
= e
->referent
;
3430 e
->referent
->body
->visit (& vut
);
3431 if (!vut
.side_effect_free_wrt (focal_vars
))
3437 if (session
.verbose
>2)
3438 clog
<< _("Eliding side-effect-free function call ") << *e
->tok
<< endl
;
3440 block
*b
= new block
;
3443 for (unsigned i
=0; i
<e
->args
.size(); i
++ )
3445 expr_statement
*es
= new expr_statement
;
3446 es
->value
= e
->args
[i
];
3447 es
->tok
= es
->value
->tok
;
3448 b
->statements
.push_back(es
);
3458 void_statement_reducer::visit_print_format (print_format
* e
)
3460 // When an sprint's return value is ignored, we can simply evaluate the
3461 // arguments in sequence
3463 if (e
->print_to_stream
|| !e
->args
.size())
3469 if (session
.verbose
>2)
3470 clog
<< _("Eliding unused print ") << *e
->tok
<< endl
;
3472 block
*b
= new block
;
3475 for (unsigned i
=0; i
<e
->args
.size(); i
++ )
3477 expr_statement
*es
= new expr_statement
;
3478 es
->value
= e
->args
[i
];
3479 es
->tok
= es
->value
->tok
;
3480 b
->statements
.push_back(es
);
3490 void_statement_reducer::reduce_target_symbol (target_symbol
* e
,
3491 expression
* operand
)
3493 // When the result of any target_symbol isn't needed, it's just as good to
3494 // evaluate the operand and any array indexes directly
3496 block
*b
= new block
;
3501 expr_statement
*es
= new expr_statement
;
3502 es
->value
= operand
;
3503 es
->tok
= es
->value
->tok
;
3504 b
->statements
.push_back(es
);
3507 for (unsigned i
=0; i
<e
->components
.size(); i
++ )
3509 if (e
->components
[i
].type
!= target_symbol::comp_expression_array_index
)
3512 expr_statement
*es
= new expr_statement
;
3513 es
->value
= e
->components
[i
].expr_index
;
3514 es
->tok
= es
->value
->tok
;
3515 b
->statements
.push_back(es
);
3525 void_statement_reducer::visit_atvar_op (atvar_op
* e
)
3527 if (session
.verbose
>2)
3528 clog
<< _("Eliding unused target symbol ") << *e
->tok
<< endl
;
3529 reduce_target_symbol (e
);
3533 void_statement_reducer::visit_target_symbol (target_symbol
* e
)
3535 if (session
.verbose
>2)
3536 clog
<< _("Eliding unused target symbol ") << *e
->tok
<< endl
;
3537 reduce_target_symbol (e
);
3541 void_statement_reducer::visit_cast_op (cast_op
* e
)
3543 if (session
.verbose
>2)
3544 clog
<< _("Eliding unused typecast ") << *e
->tok
<< endl
;
3545 reduce_target_symbol (e
, e
->operand
);
3549 void_statement_reducer::visit_autocast_op (autocast_op
* e
)
3551 if (session
.verbose
>2)
3552 clog
<< _("Eliding unused autocast ") << *e
->tok
<< endl
;
3553 reduce_target_symbol (e
, e
->operand
);
3558 void_statement_reducer::visit_defined_op (defined_op
* e
)
3560 // When the result of a @defined operation isn't needed, just elide
3561 // it entirely. Its operand $expression must already be
3562 // side-effect-free.
3564 if (session
.verbose
>2)
3565 clog
<< _("Eliding unused check ") << *e
->tok
<< endl
;
3574 void semantic_pass_opt5 (systemtap_session
& s
, bool& relaxed_p
)
3576 // Let's simplify statements with unused computed values.
3578 void_statement_reducer
vuv (s
, relaxed_p
);
3579 // This instance may be reused for multiple probe/function body trims.
3581 vuv
.focal_vars
.insert (s
.globals
.begin(), s
.globals
.end());
3583 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
3584 vuv
.replace (s
.probes
[i
]->body
);
3585 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
3586 it
!= s
.functions
.end(); it
++)
3587 vuv
.replace (it
->second
->body
);
3591 struct const_folder
: public update_visitor
3593 systemtap_session
& session
;
3596 const_folder(systemtap_session
& s
, bool& r
):
3597 session(s
), relaxed_p(r
), last_number(0), last_string(0) {}
3599 literal_number
* last_number
;
3600 literal_number
* get_number(expression
*& e
);
3601 void visit_literal_number (literal_number
* e
);
3603 literal_string
* last_string
;
3604 literal_string
* get_string(expression
*& e
);
3605 void visit_literal_string (literal_string
* e
);
3607 void get_literal(expression
*& e
, literal_number
*& n
, literal_string
*& s
);
3609 void visit_if_statement (if_statement
* s
);
3610 void visit_for_loop (for_loop
* s
);
3611 void visit_foreach_loop (foreach_loop
* s
);
3612 void visit_binary_expression (binary_expression
* e
);
3613 void visit_unary_expression (unary_expression
* e
);
3614 void visit_logical_or_expr (logical_or_expr
* e
);
3615 void visit_logical_and_expr (logical_and_expr
* e
);
3616 // void visit_regex_query (regex_query* e); // XXX: would require executing dfa at compile-time
3617 void visit_comparison (comparison
* e
);
3618 void visit_concatenation (concatenation
* e
);
3619 void visit_ternary_expression (ternary_expression
* e
);
3620 void visit_defined_op (defined_op
* e
);
3621 void visit_target_symbol (target_symbol
* e
);
3625 const_folder::get_literal(expression
*& e
,
3630 n
= (e
== last_number
) ? last_number
: NULL
;
3631 s
= (e
== last_string
) ? last_string
: NULL
;
3635 const_folder::get_number(expression
*& e
)
3638 return (e
== last_number
) ? last_number
: NULL
;
3642 const_folder::visit_literal_number (literal_number
* e
)
3649 const_folder::get_string(expression
*& e
)
3652 return (e
== last_string
) ? last_string
: NULL
;
3656 const_folder::visit_literal_string (literal_string
* e
)
3663 const_folder::visit_if_statement (if_statement
* s
)
3665 literal_number
* cond
= get_number (s
->condition
);
3668 replace (s
->thenblock
);
3669 replace (s
->elseblock
);
3674 if (session
.verbose
>2)
3675 clog
<< _F("Collapsing constant-%" PRIi64
" if-statement %s",
3676 cond
->value
, lex_cast(*s
->tok
).c_str()) << endl
;
3679 statement
* n
= cond
->value
? s
->thenblock
: s
->elseblock
;
3683 provide (new null_statement (s
->tok
));
3688 const_folder::visit_for_loop (for_loop
* s
)
3690 literal_number
* cond
= get_number (s
->cond
);
3691 if (!cond
|| cond
->value
)
3700 if (session
.verbose
>2)
3701 clog
<< _("Collapsing constantly-false for-loop ") << *s
->tok
<< endl
;
3705 s
->init
->visit (this);
3707 provide (new null_statement (s
->tok
));
3712 const_folder::visit_foreach_loop (foreach_loop
* s
)
3714 literal_number
* limit
= get_number (s
->limit
);
3715 if (!limit
|| limit
->value
> 0)
3717 for (unsigned i
= 0; i
< s
->indexes
.size(); ++i
)
3718 replace (s
->indexes
[i
]);
3726 if (session
.verbose
>2)
3727 clog
<< _("Collapsing constantly-limited foreach-loop ") << *s
->tok
<< endl
;
3730 provide (new null_statement (s
->tok
));
3735 const_folder::visit_binary_expression (binary_expression
* e
)
3738 literal_number
* left
= get_number (e
->left
);
3739 literal_number
* right
= get_number (e
->right
);
3741 if (right
&& !right
->value
&& (e
->op
== "/" || e
->op
== "%"))
3743 // Give divide-by-zero a chance to be optimized out elsewhere,
3744 // and if not it will be a runtime error anyway...
3752 value
= left
->value
+ right
->value
;
3753 else if (e
->op
== "-")
3754 value
= left
->value
- right
->value
;
3755 else if (e
->op
== "*")
3756 value
= left
->value
* right
->value
;
3757 else if (e
->op
== "&")
3758 value
= left
->value
& right
->value
;
3759 else if (e
->op
== "|")
3760 value
= left
->value
| right
->value
;
3761 else if (e
->op
== "^")
3762 value
= left
->value
^ right
->value
;
3763 else if (e
->op
== ">>")
3764 value
= left
->value
>> max(min(right
->value
, (int64_t)64), (int64_t)0);
3765 else if (e
->op
== "<<")
3766 value
= left
->value
<< max(min(right
->value
, (int64_t)64), (int64_t)0);
3767 else if (e
->op
== "/")
3768 value
= (left
->value
== LLONG_MIN
&& right
->value
== -1) ? LLONG_MIN
:
3769 left
->value
/ right
->value
;
3770 else if (e
->op
== "%")
3771 value
= (left
->value
== LLONG_MIN
&& right
->value
== -1) ? 0 :
3772 left
->value
% right
->value
;
3774 throw SEMANTIC_ERROR (_("unsupported binary operator ") + (string
)e
->op
);
3777 else if ((left
&& ((left
->value
== 0 && (e
->op
== "*" || e
->op
== "&" ||
3778 e
->op
== ">>" || e
->op
== "<<" )) ||
3779 (left
->value
==-1 && (e
->op
== "|" || e
->op
== ">>"))))
3781 (right
&& ((right
->value
== 0 && (e
->op
== "*" || e
->op
== "&")) ||
3782 (right
->value
== 1 && (e
->op
== "%")) ||
3783 (right
->value
==-1 && (e
->op
== "%" || e
->op
== "|")))))
3785 expression
* other
= left
? e
->right
: e
->left
;
3786 varuse_collecting_visitor
vu(session
);
3788 if (!vu
.side_effect_free())
3794 // we'll pass on type=pe_long inference to the expression
3795 if (other
->type
== pe_unknown
)
3796 other
->type
= pe_long
;
3797 else if (other
->type
!= pe_long
)
3799 // this mismatch was not caught in the initial type resolution pass,
3800 // generate a mismatch (left doesn't match right) error
3801 typeresolution_info
ti(session
);
3802 ti
.assert_resolvability
= true; // need this to get it throw errors
3803 ti
.mismatch_complexity
= 1; // also needed to throw errors
3808 value
= left
->value
;
3809 else if (e
->op
== "%")
3812 value
= right
->value
;
3815 else if ((left
&& ((left
->value
== 0 && (e
->op
== "+" || e
->op
== "|" ||
3817 (left
->value
== 1 && (e
->op
== "*")) ||
3818 (left
->value
==-1 && (e
->op
== "&"))))
3820 (right
&& ((right
->value
== 0 && (e
->op
== "+" || e
->op
== "-" ||
3821 e
->op
== "|" || e
->op
== "^")) ||
3822 (right
->value
== 1 && (e
->op
== "*" || e
->op
== "/")) ||
3823 (right
->value
==-1 && (e
->op
== "&")) ||
3824 (right
->value
<= 0 && (e
->op
== ">>" || e
->op
== "<<")))))
3826 if (session
.verbose
>2)
3827 clog
<< _("Collapsing constant-identity binary operator ") << *e
->tok
<< endl
;
3830 // we'll pass on type=pe_long inference to the expression
3831 expression
* other
= left
? e
->right
: e
->left
;
3832 if (other
->type
== pe_unknown
)
3833 other
->type
= pe_long
;
3834 else if (other
->type
!= pe_long
)
3836 // this mismatch was not caught in the initial type resolution pass,
3837 // generate a mismatch (left doesn't match right) error
3838 typeresolution_info
ti(session
);
3839 ti
.assert_resolvability
= true; // need this to get it throw errors
3840 ti
.mismatch_complexity
= 1; // also needed to throw errors
3854 if (session
.verbose
>2)
3855 clog
<< _F("Collapsing constant-%" PRIi64
" binary operator %s",
3856 value
, lex_cast(*e
->tok
).c_str()) << endl
;
3859 literal_number
* n
= new literal_number(value
);
3865 const_folder::visit_unary_expression (unary_expression
* e
)
3867 literal_number
* operand
= get_number (e
->operand
);
3872 if (session
.verbose
>2)
3873 clog
<< _("Collapsing constant unary ") << *e
->tok
<< endl
;
3876 literal_number
* n
= new literal_number (*operand
);
3880 else if (e
->op
== "-")
3881 n
->value
= -n
->value
;
3882 else if (e
->op
== "!")
3883 n
->value
= !n
->value
;
3884 else if (e
->op
== "~")
3885 n
->value
= ~n
->value
;
3887 throw SEMANTIC_ERROR (_("unsupported unary operator ") + (string
)e
->op
);
3893 const_folder::visit_logical_or_expr (logical_or_expr
* e
)
3896 literal_number
* left
= get_number (e
->left
);
3897 literal_number
* right
= get_number (e
->right
);
3900 value
= left
->value
|| right
->value
;
3902 else if ((left
&& left
->value
) || (right
&& right
->value
))
3904 // If the const is on the left, we get to short-circuit the right
3905 // immediately. Otherwise, we can only eliminate the LHS if it's pure.
3908 varuse_collecting_visitor
vu(session
);
3909 e
->left
->visit(&vu
);
3910 if (!vu
.side_effect_free())
3920 // We might also get rid of useless "0||x" and "x||0", except it does
3921 // normalize x to 0 or 1. We could change it to "!!x", but it's not clear
3922 // that this would gain us much.
3930 if (session
.verbose
>2)
3931 clog
<< _("Collapsing constant logical-OR ") << *e
->tok
<< endl
;
3934 literal_number
* n
= new literal_number(value
);
3940 const_folder::visit_logical_and_expr (logical_and_expr
* e
)
3943 literal_number
* left
= get_number (e
->left
);
3944 literal_number
* right
= get_number (e
->right
);
3947 value
= left
->value
&& right
->value
;
3949 else if ((left
&& !left
->value
) || (right
&& !right
->value
))
3951 // If the const is on the left, we get to short-circuit the right
3952 // immediately. Otherwise, we can only eliminate the LHS if it's pure.
3955 varuse_collecting_visitor
vu(session
);
3956 e
->left
->visit(&vu
);
3957 if (!vu
.side_effect_free())
3967 // We might also get rid of useless "1&&x" and "x&&1", except it does
3968 // normalize x to 0 or 1. We could change it to "!!x", but it's not clear
3969 // that this would gain us much.
3977 if (session
.verbose
>2)
3978 clog
<< _("Collapsing constant logical-AND ") << *e
->tok
<< endl
;
3981 literal_number
* n
= new literal_number(value
);
3987 const_folder::visit_comparison (comparison
* e
)
3991 literal_number
*left_num
, *right_num
;
3992 literal_string
*left_str
, *right_str
;
3993 get_literal(e
->left
, left_num
, left_str
);
3994 get_literal(e
->right
, right_num
, right_str
);
3996 if (left_str
&& right_str
)
3997 comp
= left_str
->value
.compare(right_str
->value
);
3999 else if (left_num
&& right_num
)
4000 comp
= left_num
->value
< right_num
->value
? -1 :
4001 left_num
->value
> right_num
->value
? 1 : 0;
4003 else if ((left_num
&& ((left_num
->value
== LLONG_MIN
&&
4004 (e
->op
== "<=" || e
->op
== ">")) ||
4005 (left_num
->value
== LLONG_MAX
&&
4006 (e
->op
== ">=" || e
->op
== "<"))))
4008 (right_num
&& ((right_num
->value
== LLONG_MIN
&&
4009 (e
->op
== ">=" || e
->op
== "<")) ||
4010 (right_num
->value
== LLONG_MAX
&&
4011 (e
->op
== "<=" || e
->op
== ">")))))
4013 expression
* other
= left_num
? e
->right
: e
->left
;
4014 varuse_collecting_visitor
vu(session
);
4016 if (!vu
.side_effect_free())
4020 if (session
.verbose
>2)
4021 clog
<< _("Collapsing constant-boundary comparison ") << *e
->tok
<< endl
;
4024 // ops <= and >= are true, < and > are false
4025 literal_number
* n
= new literal_number( e
->op
.length() == 2 );
4038 if (session
.verbose
>2)
4039 clog
<< _("Collapsing constant comparison ") << *e
->tok
<< endl
;
4045 else if (e
->op
== "!=")
4047 else if (e
->op
== "<")
4049 else if (e
->op
== ">")
4051 else if (e
->op
== "<=")
4053 else if (e
->op
== ">=")
4056 throw SEMANTIC_ERROR (_("unsupported comparison operator ") + (string
)e
->op
);
4058 literal_number
* n
= new literal_number(value
);
4064 const_folder::visit_concatenation (concatenation
* e
)
4066 literal_string
* left
= get_string (e
->left
);
4067 literal_string
* right
= get_string (e
->right
);
4071 if (session
.verbose
>2)
4072 clog
<< _("Collapsing constant concatenation ") << *e
->tok
<< endl
;
4075 literal_string
* n
= new literal_string (*left
);
4077 n
->value
= (string
)n
->value
+ (string
)right
->value
;
4080 else if ((left
&& left
->value
.empty()) ||
4081 (right
&& right
->value
.empty()))
4083 if (session
.verbose
>2)
4084 clog
<< _("Collapsing identity concatenation ") << *e
->tok
<< endl
;
4086 provide(left
? e
->right
: e
->left
);
4093 const_folder::visit_ternary_expression (ternary_expression
* e
)
4095 literal_number
* cond
= get_number (e
->cond
);
4098 replace (e
->truevalue
);
4099 replace (e
->falsevalue
);
4104 if (session
.verbose
>2)
4105 clog
<< _F("Collapsing constant-%" PRIi64
" ternary %s",
4106 cond
->value
, lex_cast(*e
->tok
).c_str()) << endl
;
4109 expression
* n
= cond
->value
? e
->truevalue
: e
->falsevalue
;
4115 const_folder::visit_defined_op (defined_op
* e
)
4117 // If a @defined makes it this far, then it is, de facto, undefined.
4119 if (session
.verbose
>2)
4120 clog
<< _("Collapsing untouched @defined check ") << *e
->tok
<< endl
;
4123 literal_number
* n
= new literal_number (0);
4129 const_folder::visit_target_symbol (target_symbol
* e
)
4131 if (session
.skip_badvars
)
4133 // Upon user request for ignoring context, the symbol is replaced
4134 // with a literal 0 and a warning message displayed
4135 // XXX this ignores possible side-effects, e.g. in array indexes
4136 literal_number
* ln_zero
= new literal_number (0);
4137 ln_zero
->tok
= e
->tok
;
4139 session
.print_warning (_("Bad $context variable being substituted with literal 0"),
4144 update_visitor::visit_target_symbol (e
);
4147 static int initial_typeres_pass(systemtap_session
& s
);
4148 static int semantic_pass_const_fold (systemtap_session
& s
, bool& relaxed_p
)
4150 // attempt an initial type resolution pass to see if there are any type
4151 // mismatches before we starting whisking away vars that get switched out
4154 // return if the initial type resolution pass reported errors (type mismatches)
4155 int rc
= initial_typeres_pass(s
);
4162 // Let's simplify statements with constant values.
4163 const_folder
cf (s
, relaxed_p
);
4164 // This instance may be reused for multiple probe/function body trims.
4166 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
4167 cf
.replace (s
.probes
[i
]->body
);
4168 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
4169 it
!= s
.functions
.end(); it
++)
4170 cf
.replace (it
->second
->body
);
4175 struct dead_control_remover
: public traversing_visitor
4177 systemtap_session
& session
;
4181 dead_control_remover(systemtap_session
& s
, bool& r
):
4182 session(s
), relaxed_p(r
), control(NULL
) {}
4184 void visit_block (block
*b
);
4186 // When a block contains any of these, the following statements are dead.
4187 void visit_return_statement (return_statement
* s
) { control
= s
; }
4188 void visit_next_statement (next_statement
* s
) { control
= s
; }
4189 void visit_break_statement (break_statement
* s
) { control
= s
; }
4190 void visit_continue_statement (continue_statement
* s
) { control
= s
; }
4194 void dead_control_remover::visit_block (block
* b
)
4196 vector
<statement
*>& vs
= b
->statements
;
4197 if (vs
.size() == 0) /* else (size_t) size()-1 => very big */
4199 for (size_t i
= 0; i
< vs
.size() - 1; ++i
)
4201 vs
[i
]->visit (this);
4202 if (vs
[i
] == control
)
4204 session
.print_warning(_("statement will never be reached"),
4206 vs
.erase(vs
.begin() + i
+ 1, vs
.end());
4214 static void semantic_pass_dead_control (systemtap_session
& s
, bool& relaxed_p
)
4216 // Let's remove code that follow unconditional control statements
4218 dead_control_remover
dc (s
, relaxed_p
);
4220 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
4221 s
.probes
[i
]->body
->visit(&dc
);
4223 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
4224 it
!= s
.functions
.end(); it
++)
4225 it
->second
->body
->visit(&dc
);
4229 struct duplicate_function_remover
: public functioncall_traversing_visitor
4231 systemtap_session
& s
;
4232 map
<functiondecl
*, functiondecl
*>& duplicate_function_map
;
4234 duplicate_function_remover(systemtap_session
& sess
,
4235 map
<functiondecl
*, functiondecl
*>&dfm
):
4236 s(sess
), duplicate_function_map(dfm
) {};
4238 void visit_functioncall (functioncall
* e
);
4242 duplicate_function_remover::visit_functioncall (functioncall
*e
)
4244 functioncall_traversing_visitor::visit_functioncall (e
);
4246 // If the current function call reference points to a function that
4247 // is a duplicate, replace it.
4248 if (duplicate_function_map
.count(e
->referent
) != 0)
4251 clog
<< _F("Changing %s reference to %s reference\n",
4252 e
->referent
->name
.to_string().c_str(),
4253 duplicate_function_map
[e
->referent
]->name
.to_string().c_str());
4254 e
->tok
= duplicate_function_map
[e
->referent
]->tok
;
4255 e
->function
= duplicate_function_map
[e
->referent
]->name
;
4256 e
->referent
= duplicate_function_map
[e
->referent
];
4261 get_functionsig (functiondecl
* f
)
4265 // Get the "name:args body" of the function in s. We have to
4266 // include the args since the function 'x1(a, b)' is different than
4267 // the function 'x2(b, a)' even if the bodies of the two functions
4268 // are exactly the same.
4272 // printsig puts f->name + ':' on the front. Remove this
4273 // (otherwise, functions would never compare equal).
4274 string str
= s
.str().erase(0, f
->name
.size() + 1);
4276 // Return the function signature.
4280 void semantic_pass_opt6 (systemtap_session
& s
, bool& relaxed_p
)
4282 // Walk through all the functions, looking for duplicates.
4283 map
<string
, functiondecl
*> functionsig_map
;
4284 map
<functiondecl
*, functiondecl
*> duplicate_function_map
;
4287 vector
<functiondecl
*> newly_zapped_functions
;
4288 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
4290 functiondecl
*fd
= it
->second
;
4291 string functionsig
= get_functionsig(fd
);
4293 if (functionsig_map
.count(functionsig
) == 0)
4295 // This function is unique. Remember it.
4296 functionsig_map
[functionsig
] = fd
;
4300 // This function is a duplicate.
4301 duplicate_function_map
[fd
] = functionsig_map
[functionsig
];
4302 newly_zapped_functions
.push_back (fd
);
4306 for (unsigned i
=0; i
<newly_zapped_functions
.size(); i
++)
4308 map
<string
,functiondecl
*>::iterator where
= s
.functions
.find (newly_zapped_functions
[i
]->name
);
4309 assert (where
!= s
.functions
.end());
4310 s
.functions
.erase (where
);
4314 // If we have duplicate functions, traverse down the tree, replacing
4315 // the appropriate function calls.
4316 // duplicate_function_remover::visit_functioncall() handles the
4317 // details of replacing the function calls.
4318 if (duplicate_function_map
.size() != 0)
4320 duplicate_function_remover
dfr (s
, duplicate_function_map
);
4322 for (unsigned i
=0; i
< s
.probes
.size(); i
++)
4323 s
.probes
[i
]->body
->visit(&dfr
);
4327 struct stable_analysis
: public embedded_tags_visitor
4330 stable_analysis(): embedded_tags_visitor(true), stable(false) {};
4332 void visit_embeddedcode (embeddedcode
* s
);
4333 void visit_functioncall (functioncall
* e
);
4336 void stable_analysis::visit_embeddedcode (embeddedcode
* s
)
4338 embedded_tags_visitor::visit_embeddedcode(s
);
4339 if (tagged_p("/* stable */"))
4341 if (stable
&& !tagged_p("/* pure */"))
4342 throw SEMANTIC_ERROR(_("stable function must also be /* pure */"),
4346 void stable_analysis::visit_functioncall (functioncall
* e
)
4350 // Examines entire subtree for any stable functioncalls.
4351 struct stable_finder
: public traversing_visitor
4354 set
<string
>& stable_fcs
;
4355 stable_finder(set
<string
>&s
): stable(false), stable_fcs(s
) {};
4356 void visit_functioncall (functioncall
* e
);
4359 void stable_finder::visit_functioncall (functioncall
* e
)
4361 if (stable_fcs
.find(e
->function
) != stable_fcs
.end())
4363 traversing_visitor::visit_functioncall(e
);
4366 // Examines current level of block for stable functioncalls.
4367 // Does not descend into sublevels.
4368 struct level_check
: public traversing_visitor
4371 set
<string
>& stable_fcs
;
4372 level_check(set
<string
>& s
): stable(false), stable_fcs(s
) {};
4374 void visit_block (block
* s
);
4375 void visit_try_block (try_block
*s
);
4376 void visit_if_statement (if_statement
* s
);
4377 void visit_for_loop (for_loop
* s
);
4378 void visit_foreach_loop (foreach_loop
* s
);
4379 void visit_functioncall (functioncall
* s
);
4382 void level_check::visit_block (block
* s
)
4386 void level_check::visit_try_block (try_block
* s
)
4388 if (s
->catch_error_var
)
4389 s
->catch_error_var
->visit(this);
4392 void level_check::visit_if_statement (if_statement
* s
)
4394 s
->condition
->visit(this);
4397 void level_check::visit_for_loop (for_loop
* s
)
4399 if (s
->init
) s
->init
->visit(this);
4400 s
->cond
->visit(this);
4401 if (s
->incr
) s
->incr
->visit(this);
4404 void level_check::visit_foreach_loop (foreach_loop
* s
)
4406 s
->base
->visit(this);
4408 for (unsigned i
=0; i
<s
->indexes
.size(); i
++)
4409 s
->indexes
[i
]->visit(this);
4412 s
->value
->visit(this);
4415 s
->limit
->visit(this);
4418 void level_check::visit_functioncall (functioncall
* e
)
4420 if (stable_fcs
.find(e
->function
) != stable_fcs
.end())
4422 traversing_visitor::visit_functioncall(e
);
4425 struct stable_functioncall_visitor
: public update_visitor
4427 systemtap_session
& session
;
4428 functiondecl
* current_function
;
4429 derived_probe
* current_probe
;
4430 set
<string
>& stable_fcs
;
4431 set
<string
> scope_vars
;
4432 map
<string
,vardecl
*> new_vars
;
4433 vector
<pair
<expr_statement
*,block
*> > new_stmts
;
4434 unsigned loop_depth
;
4437 stable_functioncall_visitor(systemtap_session
& s
, set
<string
>& sfc
):
4438 session(s
), current_function(0), current_probe(0), stable_fcs(sfc
),
4439 loop_depth(0), top_scope(0), curr_scope(0) {};
4441 statement
* convert_stmt(statement
* s
);
4442 void visit_block (block
* s
);
4443 void visit_try_block (try_block
* s
);
4444 void visit_if_statement (if_statement
* s
);
4445 void visit_for_loop (for_loop
* s
);
4446 void visit_foreach_loop (foreach_loop
* s
);
4447 void visit_functioncall (functioncall
* e
);
4450 statement
* stable_functioncall_visitor::convert_stmt (statement
* s
)
4452 if (top_scope
== 0 &&
4453 (dynamic_cast<for_loop
*>(s
) || dynamic_cast<foreach_loop
*>(s
)))
4455 stable_finder
sf(stable_fcs
);
4459 block
* b
= new block
;
4461 b
->statements
.push_back(s
);
4465 else if (top_scope
== 0 && !dynamic_cast<block
*>(s
))
4467 level_check
lc(stable_fcs
);
4471 block
* b
= new block
;
4473 b
->statements
.push_back(s
);
4481 void stable_functioncall_visitor::visit_block (block
* s
)
4483 block
* prev_top_scope
= top_scope
;
4484 block
* prev_scope
= curr_scope
;
4485 if (loop_depth
== 0)
4488 set
<string
> current_vars
= scope_vars
;
4490 update_visitor::visit_block(s
);
4492 if (loop_depth
== 0)
4493 top_scope
= prev_top_scope
;
4494 curr_scope
= prev_scope
;
4495 scope_vars
= current_vars
;
4498 void stable_functioncall_visitor::visit_try_block (try_block
* s
)
4501 s
->try_block
= convert_stmt(s
->try_block
);
4502 replace(s
->try_block
);
4503 replace(s
->catch_error_var
);
4505 s
->catch_block
= convert_stmt(s
->catch_block
);
4506 replace(s
->catch_block
);
4510 void stable_functioncall_visitor::visit_if_statement (if_statement
* s
)
4512 block
* prev_top_scope
= top_scope
;
4514 if (loop_depth
== 0)
4516 replace(s
->condition
);
4517 s
->thenblock
= convert_stmt(s
->thenblock
);
4518 replace(s
->thenblock
);
4519 if (loop_depth
== 0)
4522 s
->elseblock
= convert_stmt(s
->elseblock
);
4523 replace(s
->elseblock
);
4526 top_scope
= prev_top_scope
;
4529 void stable_functioncall_visitor::visit_for_loop (for_loop
* s
)
4535 s
->block
= convert_stmt(s
->block
);
4541 void stable_functioncall_visitor::visit_foreach_loop (foreach_loop
* s
)
4543 for (unsigned i
= 0; i
< s
->indexes
.size(); ++i
)
4544 replace(s
->indexes
[i
]);
4549 s
->block
= convert_stmt(s
->block
);
4555 void stable_functioncall_visitor::visit_functioncall (functioncall
* e
)
4557 for (unsigned i
= 0; i
< e
->args
.size(); ++i
)
4558 replace (e
->args
[i
]);
4560 if (stable_fcs
.find(e
->function
) != stable_fcs
.end())
4562 string
name("__stable_");
4563 name
.append(e
->function
).append("_value");
4565 // Variable potentially not in scope since it is in a sibling block
4566 if (scope_vars
.find(e
->function
) == scope_vars
.end())
4568 if (new_vars
.find(e
->function
) == new_vars
.end())
4570 // New variable declaration to store result of function call
4571 vardecl
* v
= new vardecl
;
4574 v
->set_arity(0, e
->tok
);
4576 if (current_function
)
4577 current_function
->locals
.push_back(v
);
4579 current_probe
->locals
.push_back(v
);
4580 new_vars
[e
->function
] = v
;
4583 symbol
* sym
= new symbol
;
4586 sym
->referent
= new_vars
[e
->function
];
4587 sym
->type
= e
->type
;
4589 functioncall
* fc
= new functioncall
;
4591 fc
->function
= e
->function
;
4592 fc
->referent
= e
->referent
;
4595 assignment
* a
= new assignment
;
4602 expr_statement
* es
= new expr_statement
;
4606 // Store location of the block to put new declaration.
4607 if (loop_depth
!= 0)
4610 new_stmts
.push_back(make_pair(es
,top_scope
));
4615 new_stmts
.push_back(make_pair(es
,curr_scope
));
4618 scope_vars
.insert(e
->function
);
4624 symbol
* sym
= new symbol
;
4627 sym
->referent
= new_vars
[e
->function
];
4628 sym
->type
= e
->type
;
4637 // Cache stable embedded-c functioncall results and replace
4638 // all calls with same name using that value to reduce duplicate
4639 // functioncall overhead. Functioncalls are pulled out of any
4640 // top-level loops and put into if/try blocks.
4641 void semantic_pass_opt7(systemtap_session
& s
)
4643 set
<string
> stable_fcs
;
4644 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
4645 it
!= s
.functions
.end(); ++it
)
4647 functiondecl
* fn
= (*it
).second
;
4649 fn
->body
->visit(&sa
);
4650 if (sa
.stable
&& fn
->formal_args
.size() == 0)
4651 stable_fcs
.insert(fn
->name
);
4654 for (vector
<derived_probe
*>::iterator it
= s
.probes
.begin();
4655 it
!= s
.probes
.end(); ++it
)
4657 stable_functioncall_visitor
t(s
, stable_fcs
);
4658 t
.current_probe
= *it
;
4659 (*it
)->body
= t
.convert_stmt((*it
)->body
);
4660 t
.replace((*it
)->body
);
4662 for (vector
<pair
<expr_statement
*,block
*> >::iterator st
= t
.new_stmts
.begin();
4663 st
!= t
.new_stmts
.end(); ++st
)
4664 st
->second
->statements
.insert(st
->second
->statements
.begin(), st
->first
);
4667 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
4668 it
!= s
.functions
.end(); ++it
)
4670 functiondecl
* fn
= (*it
).second
;
4671 stable_functioncall_visitor
t(s
, stable_fcs
);
4672 t
.current_function
= fn
;
4673 fn
->body
= t
.convert_stmt(fn
->body
);
4674 t
.replace(fn
->body
);
4676 for (vector
<pair
<expr_statement
*,block
*> >::iterator st
= t
.new_stmts
.begin();
4677 st
!= t
.new_stmts
.end(); ++st
)
4678 st
->second
->statements
.insert(st
->second
->statements
.begin(), st
->first
);
4683 semantic_pass_optimize1 (systemtap_session
& s
)
4685 // In this pass, we attempt to rewrite probe/function bodies to
4686 // eliminate some blatantly unnecessary code. This is run before
4687 // type inference, but after symbol resolution and derived_probe
4688 // creation. We run an outer "relaxation" loop that repeats the
4689 // optimizations until none of them find anything to remove.
4693 // Save the old value of suppress_warnings, as we will be changing
4695 save_and_restore
<bool> suppress_warnings(& s
.suppress_warnings
);
4697 bool relaxed_p
= false;
4698 unsigned iterations
= 0;
4701 assert_no_interrupts();
4703 relaxed_p
= true; // until proven otherwise
4705 // If the verbosity is high enough, always print warnings (overrides -w),
4706 // or if not, always suppress warnings for every itteration after the first.
4708 s
.suppress_warnings
= false;
4709 else if (iterations
> 0)
4710 s
.suppress_warnings
= true;
4714 semantic_pass_opt1 (s
, relaxed_p
);
4715 semantic_pass_opt2 (s
, relaxed_p
, iterations
); // produce some warnings only on iteration=0
4716 semantic_pass_opt3 (s
, relaxed_p
);
4717 semantic_pass_opt4 (s
, relaxed_p
);
4718 semantic_pass_opt5 (s
, relaxed_p
);
4721 // For listing mode, we need const-folding regardless of optimization so
4722 // that @defined expressions can be properly resolved. PR11360
4723 // We also want it in case variables are used in if/case expressions,
4724 // so enable always. PR11366
4725 // rc is incremented if there is an error that got reported.
4726 rc
+= semantic_pass_const_fold (s
, relaxed_p
);
4729 semantic_pass_dead_control (s
, relaxed_p
);
4739 semantic_pass_optimize2 (systemtap_session
& s
)
4741 // This is run after type inference. We run an outer "relaxation"
4742 // loop that repeats the optimizations until none of them find
4743 // anything to remove.
4747 // Save the old value of suppress_warnings, as we will be changing
4749 save_and_restore
<bool> suppress_warnings(& s
.suppress_warnings
);
4751 bool relaxed_p
= false;
4752 unsigned iterations
= 0;
4755 assert_no_interrupts();
4756 relaxed_p
= true; // until proven otherwise
4758 // If the verbosity is high enough, always print warnings (overrides -w),
4759 // or if not, always suppress warnings for every itteration after the first.
4761 s
.suppress_warnings
= false;
4762 else if (iterations
> 0)
4763 s
.suppress_warnings
= true;
4766 semantic_pass_opt6 (s
, relaxed_p
);
4772 semantic_pass_opt7(s
);
4779 // ------------------------------------------------------------------------
4782 struct autocast_expanding_visitor
: public var_expanding_visitor
4784 typeresolution_info
& ti
;
4785 autocast_expanding_visitor (typeresolution_info
& ti
): ti(ti
) {}
4787 void resolve_functioncall (functioncall
* fc
)
4789 // This is a very limited version of semantic_pass_symbols, but we're
4790 // late in the game at this point. We won't get a chance to optimize,
4791 // but for now the only functions we expect are kernel/user_string from
4792 // pretty-printing, which don't need optimization.
4794 systemtap_session
& s
= ti
.session
;
4795 size_t nfiles
= s
.files
.size();
4797 symresolution_info
sym (s
);
4798 sym
.current_function
= ti
.current_function
;
4799 sym
.current_probe
= ti
.current_probe
;
4802 // NB: synthetic functions get tacked onto the origin file, so we won't
4803 // see them growing s.files[]. Traverse it directly.
4806 functiondecl
* fd
= fc
->referent
;
4807 sym
.current_function
= fd
;
4808 sym
.current_probe
= 0;
4809 fd
->body
->visit (&sym
);
4812 while (nfiles
< s
.files
.size())
4814 stapfile
* dome
= s
.files
[nfiles
++];
4815 for (size_t i
= 0; i
< dome
->functions
.size(); ++i
)
4817 functiondecl
* fd
= dome
->functions
[i
];
4818 sym
.current_function
= fd
;
4819 sym
.current_probe
= 0;
4820 fd
->body
->visit (&sym
);
4821 // NB: not adding to s.functions just yet...
4825 // Add only the direct functions we need.
4826 functioncall_traversing_visitor ftv
;
4828 for (set
<functiondecl
*>::iterator it
= ftv
.seen
.begin();
4829 it
!= ftv
.seen
.end(); ++it
)
4831 functiondecl
* fd
= *it
;
4832 pair
<map
<string
,functiondecl
*>::iterator
,bool> inserted
=
4833 s
.functions
.insert (make_pair (fd
->name
, fd
));
4834 if (!inserted
.second
&& inserted
.first
->second
!= fd
)
4835 throw SEMANTIC_ERROR
4836 (_F("resolved function '%s' conflicts with an existing function",
4837 fd
->name
.to_string().c_str()), fc
->tok
);
4841 void visit_autocast_op (autocast_op
* e
)
4843 const bool lvalue
= is_active_lvalue (e
);
4844 const exp_type_ptr
& details
= e
->operand
->type_details
;
4845 if (details
&& !e
->saved_conversion_error
)
4847 functioncall
* fc
= details
->expand (e
, lvalue
);
4850 ti
.num_newly_resolved
++;
4852 resolve_functioncall (fc
);
4855 provide_lvalue_call (fc
);
4861 var_expanding_visitor::visit_autocast_op (e
);
4866 struct initial_typeresolution_info
: public typeresolution_info
4868 initial_typeresolution_info (systemtap_session
& s
): typeresolution_info(s
)
4871 // these expressions are not supposed to make its way to the typeresolution
4872 // pass. they probably get substituted/replaced, but since this is an initial pass
4873 // and not all substitutions are done, replace the functions that throw errors.
4874 void visit_target_symbol (target_symbol
* e
) {}
4875 void visit_atvar_op (atvar_op
* e
) {}
4876 void visit_defined_op (defined_op
* e
) {}
4877 void visit_entry_op (entry_op
* e
) {}
4878 void visit_cast_op (cast_op
* e
) {}
4881 static int initial_typeres_pass(systemtap_session
& s
)
4883 // minimal type resolution based off of semantic_pass_types(), without
4884 // checking for complete type resolutions or autocast expanding
4885 initial_typeresolution_info
ti(s
);
4887 // Globals never have detailed types.
4888 // If we null them now, then all remaining vardecls can be detailed.
4889 for (unsigned j
=0; j
<s
.globals
.size(); j
++)
4891 vardecl
* gd
= s
.globals
[j
];
4892 if (!gd
->type_details
)
4893 gd
->type_details
= ti
.null_type
;
4896 ti
.assert_resolvability
= false;
4899 assert_no_interrupts();
4901 ti
.num_newly_resolved
= 0;
4902 ti
.num_still_unresolved
= 0;
4903 ti
.num_available_autocasts
= 0;
4905 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
4906 it
!= s
.functions
.end(); it
++)
4908 assert_no_interrupts();
4910 functiondecl
* fd
= it
->second
;
4911 ti
.current_probe
= 0;
4912 ti
.current_function
= fd
;
4914 fd
->body
->visit (& ti
);
4917 for (unsigned j
=0; j
<s
.probes
.size(); j
++)
4919 assert_no_interrupts();
4921 derived_probe
* pn
= s
.probes
[j
];
4922 ti
.current_function
= 0;
4923 ti
.current_probe
= pn
;
4925 pn
->body
->visit (& ti
);
4927 probe_point
* pp
= pn
->sole_location();
4930 ti
.current_function
= 0;
4931 ti
.current_probe
= 0;
4932 ti
.t
= pe_long
; // NB: expected type
4933 pp
->condition
->visit (& ti
);
4936 if (ti
.num_newly_resolved
== 0) // converged
4938 // take into account that if there are mismatches, we'd want to know
4939 // about them incase they get whisked away, later in this process
4940 if (!ti
.assert_resolvability
&& ti
.mismatch_complexity
> 0) // found a mismatch!!
4942 ti
.assert_resolvability
= true; // report errors
4944 ti
.mismatch_complexity
= 1; // print out mismatched but not unresolved type mismatches
4950 ti
.mismatch_complexity
= 0;
4953 return s
.num_errors();
4957 semantic_pass_types (systemtap_session
& s
)
4961 // next pass: type inference
4962 unsigned iterations
= 0;
4963 typeresolution_info
ti (s
);
4965 // Globals never have detailed types.
4966 // If we null them now, then all remaining vardecls can be detailed.
4967 for (unsigned j
=0; j
<s
.globals
.size(); j
++)
4969 vardecl
* gd
= s
.globals
[j
];
4970 if (!gd
->type_details
)
4971 gd
->type_details
= ti
.null_type
;
4974 ti
.assert_resolvability
= false;
4977 assert_no_interrupts();
4980 ti
.num_newly_resolved
= 0;
4981 ti
.num_still_unresolved
= 0;
4982 ti
.num_available_autocasts
= 0;
4984 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
4985 it
!= s
.functions
.end(); it
++)
4988 assert_no_interrupts();
4990 functiondecl
* fd
= it
->second
;
4991 ti
.current_probe
= 0;
4992 ti
.current_function
= fd
;
4994 fd
->body
->visit (& ti
);
4995 // NB: we don't have to assert a known type for
4996 // functions here, to permit a "void" function.
4997 // The translator phase will omit the "retvalue".
4999 // if (fd->type == pe_unknown)
5000 // ti.unresolved (fd->tok);
5001 for (unsigned i
=0; i
< fd
->locals
.size(); ++i
)
5002 ti
.check_local (fd
->locals
[i
]);
5004 // Check and run the autocast expanding visitor.
5005 if (ti
.num_available_autocasts
> 0)
5007 autocast_expanding_visitor
aev (ti
);
5008 aev
.replace (fd
->body
);
5009 ti
.num_available_autocasts
= 0;
5012 catch (const semantic_error
& e
)
5014 throw SEMANTIC_ERROR(_F("while processing function %s",
5015 it
->second
->name
.to_string().c_str())).set_chain(e
);
5018 for (unsigned j
=0; j
<s
.probes
.size(); j
++)
5021 assert_no_interrupts();
5023 derived_probe
* pn
= s
.probes
[j
];
5024 ti
.current_function
= 0;
5025 ti
.current_probe
= pn
;
5027 pn
->body
->visit (& ti
);
5028 for (unsigned i
=0; i
< pn
->locals
.size(); ++i
)
5029 ti
.check_local (pn
->locals
[i
]);
5031 // Check and run the autocast expanding visitor.
5032 if (ti
.num_available_autocasts
> 0)
5034 autocast_expanding_visitor
aev (ti
);
5035 aev
.replace (pn
->body
);
5036 ti
.num_available_autocasts
= 0;
5039 probe_point
* pp
= pn
->sole_location();
5042 ti
.current_function
= 0;
5043 ti
.current_probe
= 0;
5044 ti
.t
= pe_long
; // NB: expected type
5045 pp
->condition
->visit (& ti
);
5048 catch (const semantic_error
& e
)
5050 throw SEMANTIC_ERROR(_F("while processing probe %s",
5051 s
.probes
[j
]->derived_locations(false).c_str())).set_chain(e
);
5054 for (unsigned j
=0; j
<s
.globals
.size(); j
++)
5056 vardecl
* gd
= s
.globals
[j
];
5057 if (gd
->type
== pe_unknown
)
5058 ti
.unresolved (gd
->tok
);
5059 if(gd
->arity
== 0 && gd
->wrap
== true)
5061 throw SEMANTIC_ERROR(_("wrapping not supported for scalars"), gd
->tok
);
5065 if (ti
.num_newly_resolved
== 0) // converged
5067 if (ti
.num_still_unresolved
== 0)
5068 break; // successfully
5069 else if (! ti
.assert_resolvability
)
5071 ti
.assert_resolvability
= true; // last pass, with error msgs
5073 ti
.mismatch_complexity
= 0; // print every kind of mismatch
5076 { // unsuccessful conclusion
5082 ti
.mismatch_complexity
= 0; // reset for next pass
5085 return rc
+ s
.num_errors();
5089 struct exp_type_null
: public exp_type_details
5091 uintptr_t id () const { return 0; }
5092 bool expandable() const { return false; }
5093 functioncall
*expand(autocast_op
*, bool) { return NULL
; }
5096 typeresolution_info::typeresolution_info (systemtap_session
& s
):
5097 session(s
), num_newly_resolved(0), num_still_unresolved(0),
5098 num_available_autocasts(0),
5099 assert_resolvability(false), mismatch_complexity(0),
5100 current_function(0), current_probe(0), t(pe_unknown
),
5101 null_type(new exp_type_null())
5107 typeresolution_info::visit_literal_number (literal_number
* e
)
5109 assert (e
->type
== pe_long
);
5110 if ((t
== e
->type
) || (t
== pe_unknown
))
5113 mismatch (e
->tok
, t
, e
->type
);
5118 typeresolution_info::visit_literal_string (literal_string
* e
)
5120 assert (e
->type
== pe_string
);
5121 if ((t
== e
->type
) || (t
== pe_unknown
))
5124 mismatch (e
->tok
, t
, e
->type
);
5129 typeresolution_info::visit_logical_or_expr (logical_or_expr
*e
)
5131 visit_binary_expression (e
);
5136 typeresolution_info::visit_logical_and_expr (logical_and_expr
*e
)
5138 visit_binary_expression (e
);
5142 typeresolution_info::visit_regex_query (regex_query
*e
)
5144 // NB: result of regex query is an integer!
5145 if (t
== pe_stats
|| t
== pe_string
)
5146 invalid (e
->tok
, t
);
5149 e
->left
->visit (this);
5151 e
->right
->visit (this); // parser ensures this is a literal known at compile time
5153 if (e
->type
== pe_unknown
)
5156 resolved (e
->tok
, e
->type
);
5162 typeresolution_info::visit_comparison (comparison
*e
)
5164 // NB: result of any comparison is an integer!
5165 if (t
== pe_stats
|| t
== pe_string
)
5166 invalid (e
->tok
, t
);
5168 t
= (e
->right
->type
!= pe_unknown
) ? e
->right
->type
: pe_unknown
;
5169 e
->left
->visit (this);
5170 t
= (e
->left
->type
!= pe_unknown
) ? e
->left
->type
: pe_unknown
;
5171 e
->right
->visit (this);
5173 if (e
->left
->type
!= pe_unknown
&&
5174 e
->right
->type
!= pe_unknown
&&
5175 e
->left
->type
!= e
->right
->type
)
5178 if (e
->type
== pe_unknown
)
5181 resolved (e
->tok
, e
->type
);
5187 typeresolution_info::visit_concatenation (concatenation
*e
)
5189 if (t
!= pe_unknown
&& t
!= pe_string
)
5190 invalid (e
->tok
, t
);
5193 e
->left
->visit (this);
5195 e
->right
->visit (this);
5197 if (e
->type
== pe_unknown
)
5199 e
->type
= pe_string
;
5200 resolved (e
->tok
, e
->type
);
5206 typeresolution_info::visit_assignment (assignment
*e
)
5209 invalid (e
->tok
, t
);
5211 if (e
->op
== "<<<") // stats aggregation
5214 invalid (e
->tok
, t
);
5217 e
->left
->visit (this);
5219 e
->right
->visit (this);
5220 if (e
->type
== pe_unknown
||
5221 e
->type
== pe_stats
)
5224 resolved (e
->tok
, e
->type
);
5228 else if (e
->left
->type
== pe_stats
)
5229 invalid (e
->left
->tok
, e
->left
->type
);
5231 else if (e
->right
->type
== pe_stats
)
5232 invalid (e
->right
->tok
, e
->right
->type
);
5234 else if (e
->op
== "+=" || // numeric only
5246 visit_binary_expression (e
);
5248 else if (e
->op
== ".=" || // string only
5251 if (t
== pe_long
|| t
== pe_stats
)
5252 invalid (e
->tok
, t
);
5255 e
->left
->visit (this);
5257 e
->right
->visit (this);
5258 if (e
->type
== pe_unknown
)
5260 e
->type
= pe_string
;
5261 resolved (e
->tok
, e
->type
);
5264 else if (e
->op
== "=") // overloaded = for string & numeric operands
5266 // logic similar to ternary_expression
5267 exp_type sub_type
= t
;
5269 // Infer types across the l/r values
5270 if (sub_type
== pe_unknown
&& e
->type
!= pe_unknown
)
5273 t
= (sub_type
!= pe_unknown
) ? sub_type
:
5274 (e
->right
->type
!= pe_unknown
) ? e
->right
->type
:
5276 e
->left
->visit (this);
5277 t
= (sub_type
!= pe_unknown
) ? sub_type
:
5278 (e
->left
->type
!= pe_unknown
) ? e
->left
->type
:
5280 e
->right
->visit (this);
5282 if ((sub_type
!= pe_unknown
) && (e
->type
== pe_unknown
))
5285 resolved (e
->tok
, e
->type
);
5287 if ((sub_type
== pe_unknown
) && (e
->left
->type
!= pe_unknown
))
5289 e
->type
= e
->left
->type
;
5290 resolved (e
->tok
, e
->type
);
5293 if (e
->left
->type
!= pe_unknown
&&
5294 e
->right
->type
!= pe_unknown
&&
5295 e
->left
->type
!= e
->right
->type
)
5298 // Propagate type details from the RHS to the assignment
5299 if (e
->type
== e
->right
->type
&&
5300 e
->right
->type_details
&& !e
->type_details
)
5301 resolved_details(e
->right
->type_details
, e
->type_details
);
5303 // Propagate type details from the assignment to the LHS
5304 if (e
->type
== e
->left
->type
&& e
->type_details
)
5306 if (e
->left
->type_details
&&
5307 *e
->left
->type_details
!= *e
->type_details
&&
5308 *e
->left
->type_details
!= *null_type
)
5309 resolved_details(null_type
, e
->left
->type_details
);
5310 else if (!e
->left
->type_details
)
5311 resolved_details(e
->type_details
, e
->left
->type_details
);
5315 throw SEMANTIC_ERROR (_("unsupported assignment operator ") + (string
)e
->op
);
5320 typeresolution_info::visit_embedded_expr (embedded_expr
*e
)
5322 if (e
->type
== pe_unknown
)
5324 if (e
->code
.find ("/* string */") != string::npos
)
5325 e
->type
= pe_string
;
5326 else // if (e->code.find ("/* long */") != string::npos)
5329 resolved (e
->tok
, e
->type
);
5335 typeresolution_info::visit_binary_expression (binary_expression
* e
)
5337 if (t
== pe_stats
|| t
== pe_string
)
5338 invalid (e
->tok
, t
);
5341 e
->left
->visit (this);
5343 e
->right
->visit (this);
5345 if (e
->left
->type
!= pe_unknown
&&
5346 e
->right
->type
!= pe_unknown
&&
5347 e
->left
->type
!= e
->right
->type
)
5350 if (e
->type
== pe_unknown
)
5353 resolved (e
->tok
, e
->type
);
5359 typeresolution_info::visit_pre_crement (pre_crement
*e
)
5361 visit_unary_expression (e
);
5366 typeresolution_info::visit_post_crement (post_crement
*e
)
5368 visit_unary_expression (e
);
5373 typeresolution_info::visit_unary_expression (unary_expression
* e
)
5375 if (t
== pe_stats
|| t
== pe_string
)
5376 invalid (e
->tok
, t
);
5379 e
->operand
->visit (this);
5381 if (e
->type
== pe_unknown
)
5384 resolved (e
->tok
, e
->type
);
5390 typeresolution_info::visit_ternary_expression (ternary_expression
* e
)
5392 exp_type sub_type
= t
;
5395 e
->cond
->visit (this);
5397 // Infer types across the true/false arms of the ternary expression.
5399 if (sub_type
== pe_unknown
&& e
->type
!= pe_unknown
)
5402 e
->truevalue
->visit (this);
5404 e
->falsevalue
->visit (this);
5406 if ((sub_type
== pe_unknown
) && (e
->type
!= pe_unknown
))
5407 ; // already resolved
5408 else if ((sub_type
!= pe_unknown
) && (e
->type
== pe_unknown
))
5411 resolved (e
->tok
, e
->type
);
5413 else if ((sub_type
== pe_unknown
) && (e
->truevalue
->type
!= pe_unknown
))
5415 e
->type
= e
->truevalue
->type
;
5416 resolved (e
->tok
, e
->type
);
5418 else if ((sub_type
== pe_unknown
) && (e
->falsevalue
->type
!= pe_unknown
))
5420 e
->type
= e
->falsevalue
->type
;
5421 resolved (e
->tok
, e
->type
);
5423 else if (e
->type
!= sub_type
)
5424 mismatch (e
->tok
, sub_type
, e
->type
);
5426 // Propagate type details from both true/false branches
5427 if (!e
->type_details
&&
5428 e
->type
== e
->truevalue
->type
&& e
->type
== e
->falsevalue
->type
&&
5429 e
->truevalue
->type_details
&& e
->falsevalue
->type_details
&&
5430 *e
->truevalue
->type_details
== *e
->falsevalue
->type_details
)
5431 resolved_details(e
->truevalue
->type_details
, e
->type_details
);
5435 template <class Referrer
, class Referent
>
5436 void resolve_2types (Referrer
* referrer
, Referent
* referent
,
5437 typeresolution_info
* r
, exp_type t
, bool accept_unknown
= false)
5439 exp_type
& re_type
= referrer
->type
;
5440 const token
* re_tok
= referrer
->tok
;
5441 exp_type
& te_type
= referent
->type
;
5443 if (t
!= pe_unknown
&& re_type
== t
&& re_type
== te_type
)
5444 ; // do nothing: all three e->types in agreement
5445 else if (t
== pe_unknown
&& re_type
!= pe_unknown
&& re_type
== te_type
)
5446 ; // do nothing: two known e->types in agreement
5447 else if (re_type
!= pe_unknown
&& te_type
!= pe_unknown
&& re_type
!= te_type
)
5448 r
->mismatch (re_tok
, re_type
, referent
); // referrer-referent
5449 else if (re_type
!= pe_unknown
&& t
!= pe_unknown
&& re_type
!= t
)
5450 r
->mismatch (re_tok
, t
, referent
); // referrer-t
5451 else if (te_type
!= pe_unknown
&& t
!= pe_unknown
&& te_type
!= t
)
5452 r
->mismatch (re_tok
, t
, referent
); // referent-t
5453 else if (re_type
== pe_unknown
&& t
!= pe_unknown
)
5455 // propagate from upstream
5457 r
->resolved (re_tok
, re_type
);
5458 // catch re_type/te_type mismatch later
5460 else if (re_type
== pe_unknown
&& te_type
!= pe_unknown
)
5462 // propagate from referent
5464 r
->resolved (re_tok
, re_type
);
5465 // catch re_type/t mismatch later
5467 else if (re_type
!= pe_unknown
&& te_type
== pe_unknown
)
5469 // propagate to referent
5471 r
->resolved (re_tok
, re_type
, referent
);
5472 // catch re_type/t mismatch later
5474 else if (! accept_unknown
)
5475 r
->unresolved (re_tok
);
5480 typeresolution_info::visit_symbol (symbol
* e
)
5482 if (e
->referent
== 0)
5483 throw SEMANTIC_ERROR (_F("internal error: unresolved symbol '%s'",
5484 e
->name
.to_string().c_str()), e
->tok
);
5486 resolve_2types (e
, e
->referent
, this, t
);
5488 if (e
->type
== e
->referent
->type
)
5490 // If both have type details, then they either must agree;
5491 // otherwise force them both to null.
5492 if (e
->type_details
&& e
->referent
->type_details
&&
5493 *e
->type_details
!= *e
->referent
->type_details
)
5495 resolved_details(null_type
, e
->type_details
);
5496 resolved_details(null_type
, e
->referent
->type_details
);
5498 else if (e
->type_details
&& !e
->referent
->type_details
)
5499 resolved_details(e
->type_details
, e
->referent
->type_details
);
5500 else if (!e
->type_details
&& e
->referent
->type_details
)
5501 resolved_details(e
->referent
->type_details
, e
->type_details
);
5507 typeresolution_info::visit_target_symbol (target_symbol
* e
)
5509 // This occurs only if a target symbol was not resolved over in
5510 // tapset.cxx land, that error was properly suppressed, and the
5511 // later unused-expression-elimination pass didn't get rid of it
5512 // either. So we have a target symbol that is believed to be of
5513 // genuine use, yet unresolved by the provider.
5515 if (session
.verbose
> 2)
5517 clog
<< _("Resolution problem with ");
5518 if (current_function
)
5520 clog
<< "function " << current_function
->name
<< endl
;
5521 current_function
->body
->print (clog
);
5524 else if (current_probe
)
5526 clog
<< "probe " << *current_probe
->sole_location() << endl
;
5527 current_probe
->body
->print (clog
);
5531 //TRANSLATORS: simply saying not an issue with a probe or function
5532 clog
<< _("other") << endl
;
5535 if (e
->saved_conversion_error
)
5536 throw (* (e
->saved_conversion_error
));
5538 throw SEMANTIC_ERROR(_("unresolved target-symbol expression"), e
->tok
);
5543 typeresolution_info::visit_atvar_op (atvar_op
* e
)
5545 // This occurs only if an @var() was not resolved over in
5546 // tapset.cxx land, that error was properly suppressed, and the
5547 // later unused-expression-elimination pass didn't get rid of it
5548 // either. So we have an @var() that is believed to be of
5549 // genuine use, yet unresolved by the provider.
5551 if (session
.verbose
> 2)
5553 clog
<< _("Resolution problem with ");
5554 if (current_function
)
5556 clog
<< "function " << current_function
->name
<< endl
;
5557 current_function
->body
->print (clog
);
5560 else if (current_probe
)
5562 clog
<< "probe " << *current_probe
->sole_location() << endl
;
5563 current_probe
->body
->print (clog
);
5567 //TRANSLATORS: simply saying not an issue with a probe or function
5568 clog
<< _("other") << endl
;
5571 if (e
->saved_conversion_error
)
5572 throw (* (e
->saved_conversion_error
));
5574 throw SEMANTIC_ERROR(_("unresolved @var() expression"), e
->tok
);
5579 typeresolution_info::visit_defined_op (defined_op
* e
)
5581 throw SEMANTIC_ERROR(_("unexpected @defined"), e
->tok
);
5586 typeresolution_info::visit_entry_op (entry_op
* e
)
5588 throw SEMANTIC_ERROR(_("@entry is only valid in .return probes"), e
->tok
);
5593 typeresolution_info::visit_cast_op (cast_op
* e
)
5595 // Like target_symbol, a cast_op shouldn't survive this far
5596 // unless it was not resolved and its value is really needed.
5597 if (e
->saved_conversion_error
)
5598 throw (* (e
->saved_conversion_error
));
5600 throw SEMANTIC_ERROR(_F("type definition '%s' not found in '%s'",
5601 e
->type_name
.to_string().c_str(),
5602 e
->module
.to_string().c_str()), e
->tok
);
5607 typeresolution_info::visit_autocast_op (autocast_op
* e
)
5609 // Like cast_op, a implicit autocast_op shouldn't survive this far
5610 // unless it was not resolved and its value is really needed.
5611 if (assert_resolvability
&& e
->saved_conversion_error
)
5612 throw (* (e
->saved_conversion_error
));
5613 else if (assert_resolvability
)
5614 throw SEMANTIC_ERROR(_("unknown type in dereference"), e
->tok
);
5617 e
->operand
->visit (this);
5619 num_still_unresolved
++;
5620 if (e
->operand
->type_details
&&
5621 e
->operand
->type_details
->expandable())
5622 num_available_autocasts
++;
5627 typeresolution_info::visit_perf_op (perf_op
* e
)
5629 // A perf_op should already be resolved
5630 if (t
== pe_stats
|| t
== pe_string
)
5631 invalid (e
->tok
, t
);
5635 // (There is no real need to visit our operand - by parser
5636 // construction, it's always a string literal, with its type already
5639 e
->operand
->visit (this);
5644 typeresolution_info::visit_arrayindex (arrayindex
* e
)
5647 symbol
*array
= NULL
;
5648 hist_op
*hist
= NULL
;
5649 classify_indexable(e
->base
, array
, hist
);
5651 // Every hist_op has type [int]:int, that is to say, every hist_op
5652 // is a pseudo-one-dimensional integer array type indexed by
5653 // integers (bucket numbers).
5657 if (e
->indexes
.size() != 1)
5658 unresolved (e
->tok
);
5660 e
->indexes
[0]->visit (this);
5661 if (e
->indexes
[0]->type
!= pe_long
)
5662 unresolved (e
->tok
);
5664 if (e
->type
!= pe_long
)
5667 resolved (e
->tok
, e
->type
);
5672 // Now we are left with "normal" map inference and index checking.
5675 assert (array
->referent
!= 0);
5676 resolve_2types (e
, array
->referent
, this, t
);
5678 // now resolve the array indexes
5680 // if (e->referent->index_types.size() == 0)
5681 // // redesignate referent as array
5682 // e->referent->set_arity (e->indexes.size ());
5684 if (e
->indexes
.size() != array
->referent
->index_types
.size())
5685 unresolved (e
->tok
); // symbol resolution should prevent this
5686 else for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
5690 expression
* ee
= e
->indexes
[i
];
5691 exp_type
& ft
= array
->referent
->index_types
[i
];
5694 exp_type at
= ee
->type
;
5696 if ((at
== pe_string
|| at
== pe_long
) && ft
== pe_unknown
)
5698 // propagate to formal type
5700 resolved (ee
->tok
, ft
, array
->referent
, i
);
5703 invalid (ee
->tok
, at
);
5705 invalid (ee
->tok
, ft
);
5706 if (at
!= pe_unknown
&& ft
!= pe_unknown
&& ft
!= at
)
5707 mismatch (ee
->tok
, ee
->type
, array
->referent
, i
);
5708 if (at
== pe_unknown
)
5709 unresolved (ee
->tok
);
5716 typeresolution_info::visit_functioncall (functioncall
* e
)
5718 if (e
->referent
== 0)
5719 throw SEMANTIC_ERROR (_F("internal error: unresolved function call to '%s'",
5720 e
->function
.to_string().c_str()), e
->tok
);
5722 resolve_2types (e
, e
->referent
, this, t
, true); // accept unknown type
5724 if (e
->type
== pe_stats
)
5725 invalid (e
->tok
, e
->type
);
5727 const exp_type_ptr
& func_type
= e
->referent
->type_details
;
5728 if (func_type
&& e
->referent
->type
== e
->type
5729 && (!e
->type_details
|| *func_type
!= *e
->type_details
))
5730 resolved_details(e
->referent
->type_details
, e
->type_details
);
5732 // now resolve the function parameters
5733 if (e
->args
.size() != e
->referent
->formal_args
.size())
5734 unresolved (e
->tok
); // symbol resolution should prevent this
5735 else for (unsigned i
=0; i
<e
->args
.size(); i
++)
5737 expression
* ee
= e
->args
[i
];
5738 exp_type
& ft
= e
->referent
->formal_args
[i
]->type
;
5739 const token
* fe_tok
= e
->referent
->formal_args
[i
]->tok
;
5742 exp_type at
= ee
->type
;
5744 if (((at
== pe_string
) || (at
== pe_long
)) && ft
== pe_unknown
)
5746 // propagate to formal arg
5748 resolved (ee
->tok
, ft
, e
->referent
->formal_args
[i
], i
);
5751 invalid (ee
->tok
, at
);
5753 invalid (fe_tok
, ft
);
5754 if (at
!= pe_unknown
&& ft
!= pe_unknown
&& ft
!= at
)
5755 mismatch (ee
->tok
, ee
->type
, e
->referent
->formal_args
[i
], i
);
5756 if (at
== pe_unknown
)
5757 unresolved (ee
->tok
);
5763 typeresolution_info::visit_block (block
* e
)
5765 for (unsigned i
=0; i
<e
->statements
.size(); i
++)
5768 e
->statements
[i
]->visit (this);
5774 typeresolution_info::visit_try_block (try_block
* e
)
5777 e
->try_block
->visit (this);
5778 if (e
->catch_error_var
)
5781 e
->catch_error_var
->visit (this);
5784 e
->catch_block
->visit (this);
5789 typeresolution_info::visit_embeddedcode (embeddedcode
* s
)
5791 // PR11573. If we have survived thus far with a piece of embedded
5792 // code that requires uprobes, we need to track this.
5794 // This is an odd place for this check, as opposed
5795 // to a separate 'optimization' pass, or c_unparser::visit_embeddedcode
5796 // over yonder in pass 3. However, we want to do it during pass 2 so
5797 // that cached sessions also get the uprobes treatment.
5798 if (! session
.need_uprobes
5799 && s
->code
.find("/* pragma:uprobes */") != string::npos
)
5801 if (session
.verbose
> 2)
5802 clog
<< _("Activating uprobes support because /* pragma:uprobes */ seen.") << endl
;
5803 session
.need_uprobes
= true;
5806 // PR15065. Likewise, we need to detect /* pragma:tagged_dfa */
5807 // before the gen_dfa_table pass. Again, the typechecking part of
5808 // pass 2 is a good place for this.
5809 if (! session
.need_tagged_dfa
5810 && s
->code
.find("/* pragma:tagged_dfa */") != string::npos
)
5812 // if (session.verbose > 2)
5813 // clog << _F("Turning on DFA subexpressions, pragma:tagged_dfa found in %s",
5814 // current_function->name.c_str()) << endl;
5815 // session.need_tagged_dfa = true;
5816 throw SEMANTIC_ERROR (_("Tagged DFA support is not yet available"), s
->tok
);
5822 typeresolution_info::visit_if_statement (if_statement
* e
)
5825 e
->condition
->visit (this);
5828 e
->thenblock
->visit (this);
5833 e
->elseblock
->visit (this);
5839 typeresolution_info::visit_for_loop (for_loop
* e
)
5842 if (e
->init
) e
->init
->visit (this);
5844 e
->cond
->visit (this);
5846 if (e
->incr
) e
->incr
->visit (this);
5848 e
->block
->visit (this);
5853 typeresolution_info::visit_foreach_loop (foreach_loop
* e
)
5855 // See also visit_arrayindex.
5856 // This is different in that, being a statement, we can't assign
5857 // a type to the outer array, only propagate to/from the indexes
5859 // if (e->referent->index_types.size() == 0)
5860 // // redesignate referent as array
5861 // e->referent->set_arity (e->indexes.size ());
5863 exp_type wanted_value
= pe_unknown
;
5864 symbol
*array
= NULL
;
5865 hist_op
*hist
= NULL
;
5866 classify_indexable(e
->base
, array
, hist
);
5870 if (e
->indexes
.size() != 1)
5871 unresolved (e
->tok
);
5873 e
->indexes
[0]->visit (this);
5874 if (e
->indexes
[0]->type
!= pe_long
)
5875 unresolved (e
->tok
);
5877 wanted_value
= pe_long
;
5882 if (e
->indexes
.size() != array
->referent
->index_types
.size())
5883 unresolved (e
->tok
); // symbol resolution should prevent this
5886 for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
5888 expression
* ee
= e
->indexes
[i
];
5889 exp_type
& ft
= array
->referent
->index_types
[i
];
5892 exp_type at
= ee
->type
;
5894 if ((at
== pe_string
|| at
== pe_long
) && ft
== pe_unknown
)
5896 // propagate to formal type
5898 resolved (ee
->tok
, ee
->type
, array
->referent
, i
);
5901 invalid (ee
->tok
, at
);
5903 invalid (ee
->tok
, ft
);
5904 if (at
!= pe_unknown
&& ft
!= pe_unknown
&& ft
!= at
)
5905 mismatch (ee
->tok
, ee
->type
, array
->referent
, i
);
5906 if (at
== pe_unknown
)
5907 unresolved (ee
->tok
);
5909 for (unsigned i
=0; i
<e
->array_slice
.size(); i
++)
5910 if (e
->array_slice
[i
])
5912 expression
* ee
= e
->array_slice
[i
];
5913 exp_type
& ft
= array
->referent
->index_types
[i
];
5916 exp_type at
= ee
->type
;
5918 if ((at
== pe_string
|| at
== pe_long
) && ft
== pe_unknown
)
5920 // propagate to formal type
5922 resolved (ee
->tok
, ee
->type
, array
->referent
, i
);
5925 invalid (ee
->tok
, at
);
5927 invalid (ee
->tok
, ft
);
5928 if (at
!= pe_unknown
&& ft
!= pe_unknown
&& ft
!= at
)
5929 mismatch (ee
->tok
, ee
->type
, array
->referent
, i
);
5930 if (at
== pe_unknown
)
5931 unresolved (ee
->tok
);
5935 array
->visit (this);
5936 wanted_value
= array
->type
;
5941 if (wanted_value
== pe_stats
)
5942 invalid(e
->value
->tok
, wanted_value
);
5943 else if (wanted_value
!= pe_unknown
)
5944 check_arg_type(wanted_value
, e
->value
);
5948 e
->value
->visit (this);
5952 /* Prevent @sum etc. aggregate sorting on non-statistics arrays. */
5953 if (wanted_value
!= pe_unknown
)
5954 if (e
->sort_aggr
!= sc_none
&& wanted_value
!= pe_stats
)
5955 invalid (array
->tok
, wanted_value
);
5960 e
->limit
->visit (this);
5964 e
->block
->visit (this);
5969 typeresolution_info::visit_null_statement (null_statement
*)
5975 typeresolution_info::visit_expr_statement (expr_statement
* e
)
5978 e
->value
->visit (this);
5982 struct delete_statement_typeresolution_info
:
5983 public throwing_visitor
5985 typeresolution_info
*parent
;
5986 delete_statement_typeresolution_info (typeresolution_info
*p
):
5987 throwing_visitor (_("invalid operand of delete expression")),
5991 void visit_arrayindex (arrayindex
* e
)
5993 parent
->visit_arrayindex (e
);
5996 void visit_symbol (symbol
* e
)
5998 exp_type ignored
= pe_unknown
;
5999 assert (e
->referent
!= 0);
6000 resolve_2types (e
, e
->referent
, parent
, ignored
);
6006 typeresolution_info::visit_delete_statement (delete_statement
* e
)
6008 delete_statement_typeresolution_info
di (this);
6010 e
->value
->visit (&di
);
6015 typeresolution_info::visit_next_statement (next_statement
*)
6021 typeresolution_info::visit_break_statement (break_statement
*)
6027 typeresolution_info::visit_continue_statement (continue_statement
*)
6033 typeresolution_info::visit_array_in (array_in
* e
)
6035 // all unary operators only work on numerics
6037 t
= pe_unknown
; // array value can be anything
6038 e
->operand
->visit (this);
6040 if (t1
== pe_unknown
&& e
->type
!= pe_unknown
)
6041 ; // already resolved
6042 else if (t1
== pe_string
|| t1
== pe_stats
)
6043 mismatch (e
->tok
, t1
, pe_long
);
6044 else if (e
->type
== pe_unknown
)
6047 resolved (e
->tok
, e
->type
);
6053 typeresolution_info::visit_return_statement (return_statement
* e
)
6055 // This is like symbol, where the referent is
6056 // the return value of the function.
6058 // translation pass will print error
6059 if (current_function
== 0)
6062 exp_type
& e_type
= current_function
->type
;
6063 t
= current_function
->type
;
6064 e
->value
->visit (this);
6066 if (e_type
!= pe_unknown
&& e
->value
->type
!= pe_unknown
6067 && e_type
!= e
->value
->type
)
6068 mismatch (e
->value
->tok
, e
->value
->type
, current_function
);
6069 if (e_type
== pe_unknown
&&
6070 (e
->value
->type
== pe_long
|| e
->value
->type
== pe_string
))
6072 // propagate non-statistics from value
6073 e_type
= e
->value
->type
;
6074 resolved (e
->value
->tok
, e_type
, current_function
);
6076 if (e
->value
->type
== pe_stats
)
6077 invalid (e
->value
->tok
, e
->value
->type
);
6079 const exp_type_ptr
& value_type
= e
->value
->type_details
;
6080 if (value_type
&& current_function
->type
== e
->value
->type
)
6082 exp_type_ptr
& func_type
= current_function
->type_details
;
6084 // The function can take on the type details of the return value.
6085 resolved_details(value_type
, func_type
);
6086 else if (*func_type
!= *value_type
&& *func_type
!= *null_type
)
6087 // Conflicting return types? NO TYPE FOR YOU!
6088 resolved_details(null_type
, func_type
);
6093 typeresolution_info::visit_print_format (print_format
* e
)
6095 size_t unresolved_args
= 0;
6099 e
->hist
->visit(this);
6102 else if (e
->print_with_format
)
6104 // If there's a format string, we can do both inference *and*
6107 // First we extract the subsequence of formatting components
6108 // which are conversions (not just literal string components)
6110 unsigned expected_num_args
= 0;
6111 std::vector
<print_format::format_component
> components
;
6112 for (size_t i
= 0; i
< e
->components
.size(); ++i
)
6114 if (e
->components
[i
].type
== print_format::conv_unspecified
)
6115 throw SEMANTIC_ERROR (_("Unspecified conversion in print operator format string"),
6117 else if (e
->components
[i
].type
== print_format::conv_literal
)
6119 components
.push_back(e
->components
[i
]);
6120 ++expected_num_args
;
6121 if (e
->components
[i
].widthtype
== print_format::width_dynamic
)
6122 ++expected_num_args
;
6123 if (e
->components
[i
].prectype
== print_format::prec_dynamic
)
6124 ++expected_num_args
;
6127 // Then we check that the number of conversions and the number
6130 if (expected_num_args
!= e
->args
.size())
6131 throw SEMANTIC_ERROR (_("Wrong number of args to formatted print operator"),
6134 // Then we check that the types of the conversions match the types
6137 for (size_t i
= 0; i
< components
.size(); ++i
)
6139 // Check the dynamic width, if specified
6140 if (components
[i
].widthtype
== print_format::width_dynamic
)
6142 check_arg_type (pe_long
, e
->args
[argno
]);
6146 // Check the dynamic precision, if specified
6147 if (components
[i
].prectype
== print_format::prec_dynamic
)
6149 check_arg_type (pe_long
, e
->args
[argno
]);
6153 exp_type wanted
= pe_unknown
;
6155 switch (components
[i
].type
)
6157 case print_format::conv_unspecified
:
6158 case print_format::conv_literal
:
6162 case print_format::conv_pointer
:
6163 case print_format::conv_number
:
6164 case print_format::conv_binary
:
6165 case print_format::conv_char
:
6166 case print_format::conv_memory
:
6167 case print_format::conv_memory_hex
:
6171 case print_format::conv_string
:
6176 assert (wanted
!= pe_unknown
);
6177 check_arg_type (wanted
, e
->args
[argno
]);
6183 // Without a format string, the best we can do is require that
6184 // each argument resolve to a concrete type.
6185 for (size_t i
= 0; i
< e
->args
.size(); ++i
)
6188 e
->args
[i
]->visit (this);
6189 if (e
->args
[i
]->type
== pe_unknown
)
6191 unresolved (e
->args
[i
]->tok
);
6197 if (unresolved_args
== 0)
6199 if (e
->type
== pe_unknown
)
6201 if (e
->print_to_stream
)
6204 e
->type
= pe_string
;
6205 resolved (e
->tok
, e
->type
);
6210 e
->type
= pe_unknown
;
6211 unresolved (e
->tok
);
6217 typeresolution_info::visit_stat_op (stat_op
* e
)
6220 e
->stat
->visit (this);
6221 if (e
->type
== pe_unknown
)
6224 resolved (e
->tok
, e
->type
);
6226 else if (e
->type
!= pe_long
)
6227 mismatch (e
->tok
, pe_long
, e
->type
);
6231 typeresolution_info::visit_hist_op (hist_op
* e
)
6234 e
->stat
->visit (this);
6239 typeresolution_info::check_arg_type (exp_type wanted
, expression
* arg
)
6244 if (arg
->type
== pe_unknown
)
6247 resolved (arg
->tok
, arg
->type
);
6249 else if (arg
->type
!= wanted
)
6251 mismatch (arg
->tok
, wanted
, arg
->type
);
6257 typeresolution_info::check_local (vardecl
* v
)
6261 num_still_unresolved
++;
6262 if (assert_resolvability
)
6264 (SEMANTIC_ERROR (_("array locals not supported, missing global declaration? "), v
->tok
));
6267 if (v
->type
== pe_unknown
)
6268 unresolved (v
->tok
);
6269 else if (v
->type
== pe_stats
)
6271 num_still_unresolved
++;
6272 if (assert_resolvability
)
6274 (SEMANTIC_ERROR (_("stat locals not supported, missing global declaration? "), v
->tok
));
6276 else if (!(v
->type
== pe_long
|| v
->type
== pe_string
))
6277 invalid (v
->tok
, v
->type
);
6282 typeresolution_info::unresolved (const token
* tok
)
6284 num_still_unresolved
++;
6286 if (assert_resolvability
&& mismatch_complexity
<= 0)
6289 msg
<< _("unresolved type ");
6290 session
.print_error (SEMANTIC_ERROR (msg
.str(), tok
));
6296 typeresolution_info::invalid (const token
* tok
, exp_type pe
)
6298 num_still_unresolved
++;
6300 if (assert_resolvability
)
6303 if (tok
&& tok
->type
== tok_operator
)
6304 msg
<< _("invalid operator");
6306 msg
<< _("invalid type ") << pe
;
6307 session
.print_error (SEMANTIC_ERROR (msg
.str(), tok
));
6312 typeresolution_info::mismatch (const binary_expression
* e
)
6314 num_still_unresolved
++;
6316 if (assert_resolvability
&& mismatch_complexity
<= 1)
6319 msg
<< _F("type mismatch: left and right sides don't agree (%s vs %s)",
6320 lex_cast(e
->left
->type
).c_str(), lex_cast(e
->right
->type
).c_str());
6321 session
.print_error (SEMANTIC_ERROR (msg
.str(), e
->tok
));
6323 else if (!assert_resolvability
)
6324 mismatch_complexity
= max(1, mismatch_complexity
);
6327 /* tok token where mismatch occurred
6328 * t1 type we expected (the 'good' type)
6329 * t2 type we received (the 'bad' type)
6332 typeresolution_info::mismatch (const token
* tok
, exp_type t1
, exp_type t2
)
6334 num_still_unresolved
++;
6336 if (assert_resolvability
&& mismatch_complexity
<= 2)
6339 msg
<< _F("type mismatch: expected %s", lex_cast(t1
).c_str());
6340 if (t2
!= pe_unknown
)
6341 msg
<< _F(" but found %s", lex_cast(t2
).c_str());
6342 session
.print_error (SEMANTIC_ERROR (msg
.str(), tok
));
6344 else if (!assert_resolvability
)
6345 mismatch_complexity
= max(2, mismatch_complexity
);
6348 /* tok token where the mismatch happened
6349 * type type we received (the 'bad' type)
6350 * decl declaration of mismatched symbol
6351 * index if index-based (array index or function arg)
6354 typeresolution_info::mismatch (const token
*tok
, exp_type type
,
6355 const symboldecl
* decl
, int index
)
6357 num_still_unresolved
++;
6359 if (assert_resolvability
&& mismatch_complexity
<= 3)
6361 assert(decl
!= NULL
);
6363 // If mismatch is against a function parameter from within the function
6364 // itself (rather than a function call), then the index will be -1. We
6365 // check here if the decl corresponds to one of the params and if so,
6366 // adjust the index.
6367 if (current_function
!= NULL
&& index
== -1)
6369 vector
<vardecl
*>& args
= current_function
->formal_args
;
6370 for (unsigned i
= 0; i
< args
.size() && index
< 0; i
++)
6371 if (args
[i
] == decl
)
6375 // get the declaration's original type and token
6376 const resolved_type
*original
= NULL
;
6377 for (vector
<resolved_type
>::const_iterator it
= resolved_types
.begin();
6378 it
!= resolved_types
.end() && original
== NULL
; ++it
)
6380 if (it
->decl
== decl
&& it
->index
== index
)
6384 // print basic mismatch msg if we couldn't find the decl (this can happen
6385 // for explicitly typed decls e.g. myvar:long or for fabricated (already
6386 // resolved) decls e.g. __perf_read_*)
6387 if (original
== NULL
)
6389 session
.print_error (SEMANTIC_ERROR (
6390 _F("type mismatch: expected %s but found %s",
6391 lex_cast(type
).c_str(),
6392 lex_cast(decl
->type
).c_str()),
6397 // print where mismatch happened and chain with origin of decl type
6402 msg
<< _F("index %d ", index
);
6403 msg
<< _F("type mismatch (%s)", lex_cast(type
).c_str());
6404 semantic_error
err(ERR_SRC
, msg
.str(), tok
);
6406 stringstream chain_msg
;
6407 chain_msg
<< _("type");
6409 chain_msg
<< _F(" of index %d", index
);
6410 chain_msg
<< _F(" was first inferred here (%s)",
6411 lex_cast(decl
->type
).c_str());
6412 semantic_error
chain(ERR_SRC
, chain_msg
.str(), original
->tok
);
6414 err
.set_chain(chain
);
6415 session
.print_error (err
);
6417 else if (!assert_resolvability
)
6418 mismatch_complexity
= max(3, mismatch_complexity
);
6422 /* tok token where resolution occurred
6423 * type type to which we resolved
6424 * decl declaration of resolved symbol
6425 * index if index-based (array index or function arg)
6428 typeresolution_info::resolved (const token
*tok
, exp_type type
,
6429 const symboldecl
* decl
, int index
)
6431 num_newly_resolved
++;
6433 // We only use the resolved_types vector to give better mismatch messages
6434 // involving symbols. So don't bother adding it if we're not given a decl
6437 // As a fail-safe, if the decl & index is already in the vector, then
6438 // modify it instead of adding another one to ensure uniqueness. This
6439 // should never happen since we only call resolved once for each decl &
6440 // index, but better safe than sorry. (IE. if it does happen, better have
6441 // the latest resolution info for better mismatch reporting later).
6442 for (unsigned i
= 0; i
< resolved_types
.size(); i
++)
6444 if (resolved_types
[i
].decl
== decl
6445 && resolved_types
[i
].index
== index
)
6447 resolved_types
[i
].tok
= tok
;
6451 resolved_type
res(tok
, decl
, index
);
6452 resolved_types
.push_back(res
);
6457 typeresolution_info::resolved_details (const exp_type_ptr
& src
,
6460 num_newly_resolved
++;
6464 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */