1 // elaboration functions
2 // Copyright (C) 2005-2014 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"
21 #include <sys/utsname.h>
23 #define __STDC_FORMAT_MACROS
41 // ------------------------------------------------------------------------
43 // Used in probe_point condition construction. Either argument may be
44 // NULL; if both, return NULL too. Resulting expression is a deep
45 // copy for symbol resolution purposes.
46 expression
* add_condition (expression
* a
, expression
* b
)
48 if (!a
&& !b
) return 0;
49 if (! a
) return deep_copy_visitor::deep_copy(b
);
50 if (! b
) return deep_copy_visitor::deep_copy(a
);
55 la
.tok
= a
->tok
; // or could be b->tok
56 return deep_copy_visitor::deep_copy(& la
);
59 // ------------------------------------------------------------------------
63 derived_probe::derived_probe (probe
*p
, probe_point
*l
, bool rewrite_loc
):
64 base (p
), base_pp(l
), group(NULL
), sdt_semaphore_addr(0),
65 session_index((unsigned)-1)
69 this->privileged
= p
->privileged
;
70 this->body
= deep_copy_visitor::deep_copy(p
->body
);
73 // make a copy for subclasses which want to rewrite the location
75 l
= new probe_point(*l
);
76 this->locations
.push_back (l
);
81 derived_probe::printsig (ostream
& o
) const
88 derived_probe::printsig_nested (ostream
& o
) const
90 // We'd like to enclose the probe derivation chain in a /* */
91 // comment delimiter. But just printing /* base->printsig() */ is
92 // not enough, since base might itself be a derived_probe. So we,
93 // er, "cleverly" encode our nesting state as a formatting flag for
95 ios::fmtflags f
= o
.flags (ios::internal
);
96 if (f
& ios::internal
)
115 derived_probe::collect_derivation_chain (std::vector
<probe
*> &probes_list
) const
117 probes_list
.push_back(const_cast<derived_probe
*>(this));
118 base
->collect_derivation_chain(probes_list
);
123 derived_probe::collect_derivation_pp_chain (std::vector
<probe_point
*> &pp_list
) const
125 pp_list
.push_back(const_cast<probe_point
*>(this->sole_location()));
126 base
->collect_derivation_pp_chain(pp_list
);
131 derived_probe::derived_locations ()
134 vector
<probe_point
*> reference_point
;
135 collect_derivation_pp_chain(reference_point
);
136 if (reference_point
.size() > 0)
137 for(unsigned i
=1; i
<reference_point
.size(); ++i
)
138 o
<< " from: " << reference_point
[i
]->str(false); // no ?,!,etc
144 derived_probe::sole_location () const
146 if (locations
.size() == 0 || locations
.size() > 1)
147 throw SEMANTIC_ERROR (_N("derived_probe with no locations",
148 "derived_probe with too many locations",
149 locations
.size()), this->tok
);
156 derived_probe::script_location () const
158 // This feeds function::pn() in the tapset, which is documented as the
159 // script-level probe point expression, *after wildcard expansion*.
160 vector
<probe_point
*> chain
;
161 collect_derivation_pp_chain (chain
);
163 // Go backwards until we hit the first well-formed probe point
164 for (int i
=chain
.size()-1; i
>=0; i
--)
165 if (chain
[i
]->well_formed
)
168 // If that didn't work, just fallback to -something-.
169 return sole_location();
174 derived_probe::emit_privilege_assertion (translator_output
* o
)
176 // Emit code which will cause compilation to fail if it is compiled in
177 // unprivileged mode.
178 o
->newline() << "#if ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPDEV) && \\";
179 o
->newline() << " ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPSYS)";
180 o
->newline() << "#error Internal Error: Probe ";
181 probe::printsig (o
->line());
182 o
->line() << " generated in --unprivileged mode";
183 o
->newline() << "#endif";
188 derived_probe::emit_process_owner_assertion (translator_output
* o
)
190 // Emit code which will abort should the current target not belong to the
191 // user in unprivileged mode.
192 o
->newline() << "#if ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPDEV) && \\";
193 o
->newline() << " ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPSYS)";
194 o
->newline(1) << "if (! is_myproc ()) {";
195 o
->newline(1) << "snprintf(c->error_buffer, sizeof(c->error_buffer),";
196 o
->newline() << " \"Internal Error: Process %d does not belong to user %d in probe %s in --unprivileged mode\",";
197 o
->newline() << " current->tgid, _stp_uid, c->probe_point);";
198 o
->newline() << "c->last_error = c->error_buffer;";
199 // NB: since this check occurs before probe locking, its exit should
200 // not be a "goto out", which would attempt unlocking.
201 o
->newline() << "return;";
202 o
->newline(-1) << "}";
203 o
->newline(-1) << "#endif";
207 derived_probe::print_dupe_stamp_unprivileged(ostream
& o
)
209 o
<< _("unprivileged users: authorized") << endl
;
213 derived_probe::print_dupe_stamp_unprivileged_process_owner(ostream
& o
)
215 o
<< _("unprivileged users: authorized for process owner") << endl
;
218 // ------------------------------------------------------------------------
219 // Members of derived_probe_builder
222 derived_probe_builder::build_with_suffix(systemtap_session
& sess
,
224 probe_point
* location
,
225 std::map
<std::string
, literal
*>
227 std::vector
<derived_probe
*>
229 std::vector
<probe_point::component
*>
231 // XXX perhaps build the probe if suffix is empty?
232 // if (suffix.empty()) {
233 // build (sess, use, location, parameters, finished_results);
236 throw SEMANTIC_ERROR (_("invalid suffix for probe"));
240 derived_probe_builder::get_param (std::map
<std::string
, literal
*> const & params
,
241 const std::string
& key
,
244 map
<string
, literal
*>::const_iterator i
= params
.find (key
);
245 if (i
== params
.end())
247 literal_string
* ls
= dynamic_cast<literal_string
*>(i
->second
);
256 derived_probe_builder::get_param (std::map
<std::string
, literal
*> const & params
,
257 const std::string
& key
,
260 map
<string
, literal
*>::const_iterator i
= params
.find (key
);
261 if (i
== params
.end())
263 if (i
->second
== NULL
)
265 literal_number
* ln
= dynamic_cast<literal_number
*>(i
->second
);
274 derived_probe_builder::has_null_param (std::map
<std::string
, literal
*> const & params
,
275 const std::string
& key
)
277 map
<string
, literal
*>::const_iterator i
= params
.find(key
);
278 return (i
!= params
.end() && i
->second
== NULL
);
282 derived_probe_builder::has_param (std::map
<std::string
, literal
*> const & params
,
283 const std::string
& key
)
285 return (params
.find(key
) != params
.end());
288 // ------------------------------------------------------------------------
289 // Members of match_key.
291 match_key::match_key(string
const & n
)
293 have_parameter(false),
294 parameter_type(pe_unknown
)
298 match_key::match_key(probe_point::component
const & c
)
300 have_parameter(c
.arg
!= NULL
),
301 parameter_type(c
.arg
? c
.arg
->type
: pe_unknown
)
306 match_key::with_number()
308 have_parameter
= true;
309 parameter_type
= pe_long
;
314 match_key::with_string()
316 have_parameter
= true;
317 parameter_type
= pe_string
;
322 match_key::str() const
325 switch (parameter_type
)
327 case pe_string
: return name
+ "(string)";
328 case pe_long
: return name
+ "(number)";
329 default: return name
+ "(...)";
335 match_key::operator<(match_key
const & other
) const
337 return ((name
< other
.name
)
339 || (name
== other
.name
340 && have_parameter
< other
.have_parameter
)
342 || (name
== other
.name
343 && have_parameter
== other
.have_parameter
344 && parameter_type
< other
.parameter_type
));
348 // NB: these are only used in the probe point name components, where
349 // only "*" is permitted.
351 // Within module("bar"), function("foo"), process("baz") strings, real
352 // wildcards are permitted too. See also util.h:contains_glob_chars
355 isglob(string
const & str
)
357 return(str
.find('*') != str
.npos
);
361 isdoubleglob(string
const & str
)
363 return(str
.find("**") != str
.npos
);
367 match_key::globmatch(match_key
const & other
) const
369 const char *other_str
= other
.name
.c_str();
370 const char *name_str
= name
.c_str();
372 return ((fnmatch(name_str
, other_str
, FNM_NOESCAPE
) == 0)
373 && have_parameter
== other
.have_parameter
374 && parameter_type
== other
.parameter_type
);
377 // ------------------------------------------------------------------------
378 // Members of match_node
379 // ------------------------------------------------------------------------
381 match_node::match_node() :
382 privilege(privilege_t (pr_stapdev
| pr_stapsys
))
387 match_node::bind(match_key
const & k
)
390 throw SEMANTIC_ERROR(_("invalid use of wildcard probe point component"));
392 map
<match_key
, match_node
*>::const_iterator i
= sub
.find(k
);
395 match_node
* n
= new match_node();
396 sub
.insert(make_pair(k
, n
));
401 match_node::bind(derived_probe_builder
* e
)
407 match_node::bind(string
const & k
)
409 return bind(match_key(k
));
413 match_node::bind_str(string
const & k
)
415 return bind(match_key(k
).with_string());
419 match_node::bind_num(string
const & k
)
421 return bind(match_key(k
).with_number());
425 match_node::bind_privilege(privilege_t p
)
432 match_node::find_and_build (systemtap_session
& s
,
433 probe
* p
, probe_point
*loc
, unsigned pos
,
434 vector
<derived_probe
*>& results
)
436 assert (pos
<= loc
->components
.size());
437 if (pos
== loc
->components
.size()) // matched all probe point components so far
442 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
443 alternatives
+= string(" ") + i
->first
.str();
445 throw SEMANTIC_ERROR (_F("probe point truncated (follow: %s)",
446 alternatives
.c_str()),
447 loc
->components
.back()->tok
);
450 if (! pr_contains (privilege
, s
.privilege
))
452 throw SEMANTIC_ERROR (_F("probe point is not allowed for --privilege=%s",
453 pr_name (s
.privilege
)),
454 loc
->components
.back()->tok
);
457 map
<string
, literal
*> param_map
;
458 for (unsigned i
=0; i
<pos
; i
++)
459 param_map
[loc
->components
[i
]->functor
] = loc
->components
[i
]->arg
;
462 // Iterate over all bound builders
463 for (unsigned k
=0; k
<ends
.size(); k
++)
465 derived_probe_builder
*b
= ends
[k
];
466 b
->build (s
, p
, loc
, param_map
, results
);
469 else if (isdoubleglob(loc
->components
[pos
]->functor
)) // ** wildcard?
471 unsigned int num_results
= results
.size();
473 // When faced with "foo**bar", we try "foo*bar" and "foo*.**bar"
475 const probe_point::component
*comp
= loc
->components
[pos
];
476 const string
&functor
= comp
->functor
;
477 size_t glob_start
= functor
.find("**");
478 size_t glob_end
= functor
.find_first_not_of('*', glob_start
);
479 const string prefix
= functor
.substr(0, glob_start
);
480 const string suffix
= ((glob_end
!= string::npos
) ?
481 functor
.substr(glob_end
) : "");
483 // Synthesize "foo*bar"
484 probe_point
*simple_pp
= new probe_point(*loc
);
485 simple_pp
->from_glob
= true;
486 probe_point::component
*simple_comp
= new probe_point::component(*comp
);
487 simple_comp
->functor
= prefix
+ "*" + suffix
;
488 simple_pp
->components
[pos
] = simple_comp
;
491 find_and_build (s
, p
, simple_pp
, pos
, results
);
493 catch (const semantic_error
& e
)
495 // Ignore semantic_errors.
498 // Cleanup if we didn't find anything
499 if (results
.size() == num_results
)
505 num_results
= results
.size();
507 // Synthesize "foo*.**bar"
508 // NB: any component arg should attach to the latter part only
509 probe_point
*expanded_pp
= new probe_point(*loc
);
510 expanded_pp
->from_glob
= true;
511 probe_point::component
*expanded_comp_pre
= new probe_point::component(*comp
);
512 expanded_comp_pre
->functor
= prefix
+ "*";
513 expanded_comp_pre
->arg
= NULL
;
514 probe_point::component
*expanded_comp_post
= new probe_point::component(*comp
);
515 expanded_comp_post
->functor
= "**" + suffix
;
516 expanded_pp
->components
[pos
] = expanded_comp_pre
;
517 expanded_pp
->components
.insert(expanded_pp
->components
.begin() + pos
+ 1,
521 find_and_build (s
, p
, expanded_pp
, pos
, results
);
523 catch (const semantic_error
& e
)
525 // Ignore semantic_errors.
528 // Cleanup if we didn't find anything
529 if (results
.size() == num_results
)
532 delete expanded_comp_pre
;
533 delete expanded_comp_post
;
536 // Try suffix expansion only if no matches found:
537 if (num_results
== results
.size())
538 this->try_suffix_expansion (s
, p
, loc
, pos
, results
);
540 if (! loc
->optional
&& num_results
== results
.size())
542 // We didn't find any wildcard matches (since the size of
543 // the result vector didn't change). Throw an error.
544 string sugs
= suggest_functors(functor
);
545 throw SEMANTIC_ERROR (_F("probe point mismatch: didn't find any wildcard matches%s",
546 sugs
.empty() ? "" : (" (similar: " + sugs
+ ")").c_str()),
550 else if (isglob(loc
->components
[pos
]->functor
)) // wildcard?
552 match_key
match (* loc
->components
[pos
]);
554 // Call find_and_build for each possible match. Ignore errors -
555 // unless we don't find any match.
556 unsigned int num_results
= results
.size();
557 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
559 const match_key
& subkey
= i
->first
;
560 match_node
* subnode
= i
->second
;
562 assert_no_interrupts();
564 if (match
.globmatch(subkey
))
567 clog
<< _F("wildcard '%s' matched '%s'",
568 loc
->components
[pos
]->functor
.c_str(),
569 subkey
.name
.c_str()) << endl
;
571 // When we have a wildcard, we need to create a copy of
572 // the probe point. Then we'll create a copy of the
573 // wildcard component, and substitute the non-wildcard
575 probe_point
*non_wildcard_pp
= new probe_point(*loc
);
576 non_wildcard_pp
->from_glob
= true;
577 probe_point::component
*non_wildcard_component
578 = new probe_point::component(*loc
->components
[pos
]);
579 non_wildcard_component
->functor
= subkey
.name
;
580 non_wildcard_pp
->components
[pos
] = non_wildcard_component
;
582 // NB: probe conditions are not attached at the wildcard
583 // (component/functor) level, but at the overall
584 // probe_point level.
586 unsigned int inner_results
= results
.size();
588 // recurse (with the non-wildcard probe point)
591 subnode
->find_and_build (s
, p
, non_wildcard_pp
, pos
+1,
594 catch (const semantic_error
& e
)
596 // Ignore semantic_errors while expanding wildcards.
597 // If we get done and nothing was expanded, the code
598 // following the loop will complain.
601 if (results
.size() == inner_results
)
603 // If this wildcard didn't match, cleanup.
604 delete non_wildcard_pp
;
605 delete non_wildcard_component
;
610 // Try suffix expansion only if no matches found:
611 if (num_results
== results
.size())
612 this->try_suffix_expansion (s
, p
, loc
, pos
, results
);
614 if (! loc
->optional
&& num_results
== results
.size())
616 // We didn't find any wildcard matches (since the size of
617 // the result vector didn't change). Throw an error.
618 string sugs
= suggest_functors(loc
->components
[pos
]->functor
);
619 throw SEMANTIC_ERROR (_F("probe point mismatch: didn't find any wildcard matches%s",
620 sugs
.empty() ? "" : (" (similar: " + sugs
+ ")").c_str()),
621 loc
->components
[pos
]->tok
);
626 match_key
match (* loc
->components
[pos
]);
627 sub_map_iterator_t i
= sub
.find (match
);
629 if (i
!= sub
.end()) // match found
631 match_node
* subnode
= i
->second
;
633 subnode
->find_and_build (s
, p
, loc
, pos
+1, results
);
637 unsigned int num_results
= results
.size();
638 this->try_suffix_expansion (s
, p
, loc
, pos
, results
);
640 // XXX: how to correctly report alternatives + position numbers
641 // for alias suffixes? file a separate PR to address the issue
642 if (! loc
->optional
&& num_results
== results
.size())
644 // We didn't find any alias suffixes (since the size of the
645 // result vector didn't change). Throw an error.
646 string sugs
= suggest_functors(loc
->components
[pos
]->functor
);
647 throw SEMANTIC_ERROR (_F("probe point mismatch%s",
648 sugs
.empty() ? "" : (" (similar: " + sugs
+ ")").c_str()),
649 loc
->components
[pos
]->tok
);
655 match_node::suggest_functors(string functor
)
657 // only use prefix if globby (and prefix is non-empty)
658 size_t glob
= functor
.find('*');
659 if (glob
!= string::npos
&& glob
!= 0)
664 set
<string
> functors
;
665 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
667 string ftor
= i
->first
.str();
668 if (ftor
.find('(') != string::npos
) // trim any parameter
669 ftor
.erase(ftor
.find('('));
670 functors
.insert(ftor
);
672 return levenshtein_suggest(functor
, functors
, 5); // print top 5
676 match_node::try_suffix_expansion (systemtap_session
& s
,
677 probe
*p
, probe_point
*loc
, unsigned pos
,
678 vector
<derived_probe
*>& results
)
680 // PR12210: match alias suffixes. If the components thus far
681 // have been matched, but there is an additional unknown
682 // suffix, we have a potential alias suffix on our hands. We
683 // need to expand the preceding components as probe aliases,
684 // reattach the suffix, and re-run derive_probes() on the
685 // resulting expansion. This is done by the routine
686 // build_with_suffix().
688 if (strverscmp(s
.compatible
.c_str(), "2.0") >= 0)
690 // XXX: technically, param_map isn't used here. So don't
691 // bother actually assembling it unless some
692 // derived_probe_builder appears that actually takes
693 // suffixes *and* consults parameters (currently no such
695 map
<string
, literal
*> param_map
;
696 // for (unsigned i=0; i<pos; i++)
697 // param_map[loc->components[i]->functor] = loc->components[i]->arg;
700 vector
<probe_point::component
*> suffix (loc
->components
.begin()+pos
,
701 loc
->components
.end());
703 // Multiple derived_probe_builders may be bound at a
704 // match_node due to the possibility of multiply defined
706 for (unsigned k
=0; k
< ends
.size(); k
++)
708 derived_probe_builder
*b
= ends
[k
];
711 b
->build_with_suffix (s
, p
, loc
, param_map
, results
, suffix
);
713 catch (const recursive_expansion_error
&e
)
716 throw semantic_error(e
);
718 catch (const semantic_error
&e
)
720 // Adjust source coordinate and re-throw:
722 throw semantic_error(e
.errsrc
, e
.what(), loc
->components
[pos
]->tok
);
730 match_node::build_no_more (systemtap_session
& s
)
732 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
733 i
->second
->build_no_more (s
);
734 for (unsigned k
=0; k
<ends
.size(); k
++)
736 derived_probe_builder
*b
= ends
[k
];
737 b
->build_no_more (s
);
742 match_node::dump (systemtap_session
&s
, const string
&name
)
744 // Dump this node, if it is complete.
745 for (unsigned k
=0; k
<ends
.size(); k
++)
747 // Don't print aliases at all (for now) until we can figure out how to determine whether
748 // the probes they resolve to are ok in unprivileged mode.
749 if (ends
[k
]->is_alias ())
752 // In unprivileged mode, don't show the probes which are not allowed for unprivileged
754 if (pr_contains (privilege
, s
.privilege
))
756 cout
<< name
<< endl
;
757 break; // we need only print one instance.
761 // Recursively dump the children of this node
765 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
767 i
->second
->dump (s
, name
+ dot
+ i
->first
.str());
772 // ------------------------------------------------------------------------
774 // ------------------------------------------------------------------------
776 struct alias_derived_probe
: public derived_probe
778 alias_derived_probe (probe
* base
, probe_point
*l
, const probe_alias
*a
,
779 const vector
<probe_point::component
*> *suffix
= 0);
780 ~alias_derived_probe();
782 void upchuck () { throw SEMANTIC_ERROR (_("inappropriate"), this->tok
); }
784 // Alias probes are immediately expanded to other derived_probe
785 // types, and are not themselves emitted or listed in
786 // systemtap_session.probes
788 void join_group (systemtap_session
&) { upchuck (); }
790 virtual const probe_alias
*get_alias () const { return alias
; }
791 virtual probe_point
*get_alias_loc () const { return alias_loc
; }
792 virtual probe_point
*sole_location () const;
795 const probe_alias
*alias
; // Used to check for recursion
796 probe_point
*alias_loc
; // Hack to recover full probe name
800 alias_derived_probe::alias_derived_probe(probe
*base
, probe_point
*l
,
801 const probe_alias
*a
,
802 const vector
<probe_point::component
*>
804 derived_probe (base
, l
), alias(a
)
806 // XXX pretty nasty -- this was cribbed from printscript() in main.cxx
807 assert (alias
->alias_names
.size() >= 1);
808 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
809 alias_loc
->well_formed
= true;
810 vector
<probe_point::component
*>::const_iterator it
;
811 for (it
= suffix
->begin(); it
!= suffix
->end(); ++it
)
813 alias_loc
->components
.push_back(*it
);
814 if (isglob((*it
)->functor
))
815 alias_loc
->well_formed
= false; // needs further derivation
819 alias_derived_probe::~alias_derived_probe ()
826 alias_derived_probe::sole_location () const
828 return const_cast<probe_point
*>(alias_loc
);
833 alias_expansion_builder::build(systemtap_session
& sess
,
835 probe_point
* location
,
836 std::map
<std::string
, literal
*>
838 vector
<derived_probe
*> & finished_results
)
840 vector
<probe_point::component
*> empty_suffix
;
841 build_with_suffix (sess
, use
, location
, parameters
,
842 finished_results
, empty_suffix
);
846 alias_expansion_builder::build_with_suffix(systemtap_session
& sess
,
848 probe_point
* location
,
849 std::map
<std::string
, literal
*>
851 vector
<derived_probe
*>
853 vector
<probe_point::component
*>
856 // Don't build the alias expansion if infinite recursion is detected.
857 if (checkForRecursiveExpansion (use
)) {
859 msg
<< _F("recursive loop in alias expansion of %s at %s",
860 lex_cast(*location
).c_str(), lex_cast(location
->components
.front()->tok
->location
).c_str());
861 // semantic_errors thrown here might be ignored, so we need a special class:
862 throw recursive_expansion_error (msg
.str());
863 // XXX The point of throwing this custom error is to suppress a
864 // cascade of "probe mismatch" messages that appear in addition to
865 // the error. The current approach suppresses most of the error
866 // cascade, but leaves one spurious error; in any case, the way
867 // this particular error is reported could be improved.
870 // We're going to build a new probe and wrap it up in an
871 // alias_expansion_probe so that the expansion loop recognizes it as
872 // such and re-expands its expansion.
874 alias_derived_probe
* n
= new alias_derived_probe (use
, location
/* soon overwritten */, this->alias
, &suffix
);
875 n
->body
= new block();
877 // The new probe gets a deep copy of the location list of the alias
878 // (with incoming condition joined) plus the suffix (if any),
879 n
->locations
.clear();
880 for (unsigned i
=0; i
<alias
->locations
.size(); i
++)
882 probe_point
*pp
= new probe_point(*alias
->locations
[i
]);
883 // if the original pp that gave rise to the alias we're building was from
884 // a globby probe, then inherit globbiness
885 pp
->from_glob
= location
->from_glob
;
886 pp
->components
.insert(pp
->components
.end(), suffix
.begin(), suffix
.end());
887 pp
->condition
= add_condition (pp
->condition
, location
->condition
);
888 n
->locations
.push_back(pp
);
891 // the token location of the alias,
892 n
->tok
= location
->components
.front()->tok
;
894 // and statements representing the concatenation of the alias'
895 // body with the use's.
897 // NB: locals are *not* copied forward, from either alias or
898 // use. The expansion should have its locals re-inferred since
899 // there's concatenated code here and we only want one vardecl per
900 // resulting variable.
902 if (alias
->epilogue_style
)
903 n
->body
= new block (use
->body
, alias
->body
);
905 n
->body
= new block (alias
->body
, use
->body
);
907 unsigned old_num_results
= finished_results
.size();
908 // If expanding for an alias suffix, be sure to pass on any errors
909 // to the caller instead of printing them in derive_probes():
910 derive_probes (sess
, n
, finished_results
, location
->optional
, !suffix
.empty());
912 // Check whether we resolved something. If so, put the
913 // whole library into the queue if not already there.
914 if (finished_results
.size() > old_num_results
)
916 stapfile
*f
= alias
->tok
->location
.file
;
917 if (find (sess
.files
.begin(), sess
.files
.end(), f
)
919 sess
.files
.push_back (f
);
924 alias_expansion_builder::checkForRecursiveExpansion (probe
*use
)
926 // Collect the derivation chain of this probe.
927 vector
<probe
*>derivations
;
928 use
->collect_derivation_chain (derivations
);
930 // Check all probe points in the alias expansion against the currently-being-expanded probe point
931 // of each of the probes in the derivation chain, looking for a match. This
932 // indicates infinite recursion.
933 // The first element of the derivation chain will be the derived_probe representing 'use', so
934 // start the search with the second element.
935 assert (derivations
.size() > 0);
936 assert (derivations
[0] == use
);
937 for (unsigned d
= 1; d
< derivations
.size(); ++d
) {
938 if (use
->get_alias() == derivations
[d
]->get_alias())
939 return true; // recursion detected
945 // ------------------------------------------------------------------------
947 // ------------------------------------------------------------------------
949 static unsigned max_recursion
= 100;
955 recursion_guard(unsigned & i
) : i(i
)
957 if (i
> max_recursion
)
958 throw SEMANTIC_ERROR(_("recursion limit reached"));
967 // The match-and-expand loop.
969 derive_probes (systemtap_session
& s
,
970 probe
*p
, vector
<derived_probe
*>& dps
,
974 // We need a static to track whether the current probe is optional so that
975 // even if we recurse into derive_probes with optional = false, errors will
976 // still be ignored. The undo_parent_optional bool ensures we reset the
977 // static at the same level we had it set.
978 static bool parent_optional
= false;
979 bool undo_parent_optional
= false;
981 if (optional
&& !parent_optional
)
983 parent_optional
= true;
984 undo_parent_optional
= true;
987 vector
<semantic_error
> optional_errs
;
989 for (unsigned i
= 0; i
< p
->locations
.size(); ++i
)
991 assert_no_interrupts();
993 probe_point
*loc
= p
->locations
[i
];
996 clog
<< "derive-probes " << *loc
<< endl
;
1000 unsigned num_atbegin
= dps
.size();
1004 s
.pattern_root
->find_and_build (s
, p
, loc
, 0, dps
); // <-- actual derivation!
1006 catch (const semantic_error
& e
)
1008 if (!loc
->optional
&& !parent_optional
)
1009 throw semantic_error(e
);
1010 else /* tolerate failure for optional probe */
1012 // remember err, we will print it (in catch block) if any
1013 // non-optional loc fails to resolve
1014 semantic_error
err(ERR_SRC
, _("while resolving probe point"),
1015 loc
->components
[0]->tok
, NULL
, &e
);
1016 optional_errs
.push_back(err
);
1021 unsigned num_atend
= dps
.size();
1023 if (! (loc
->optional
||parent_optional
) && // something required, but
1024 num_atbegin
== num_atend
) // nothing new derived!
1025 throw SEMANTIC_ERROR (_("no match"));
1027 if (loc
->sufficient
&& (num_atend
> num_atbegin
))
1031 clog
<< "Probe point ";
1032 p
->locations
[i
]->print(clog
);
1033 clog
<< " sufficient, skipped";
1034 for (unsigned j
= i
+1; j
< p
->locations
.size(); ++j
)
1037 p
->locations
[j
]->print(clog
);
1041 break; // we need not try to derive for any other locations
1044 catch (const semantic_error
& e
)
1046 // The rethrow_errors parameter lets the caller decide an
1047 // alternative to printing the error. This is necessary when
1048 // calling derive_probes() recursively during expansion of
1049 // an alias with suffix -- any message printed here would
1050 // point to the alias declaration and not the invalid suffix
1051 // usage, so the caller needs to catch the error themselves
1052 // and print a more appropriate message.
1055 throw semantic_error(e
);
1057 // Only output in dump mode if -vv is supplied:
1058 else if (!s
.dump_mode
|| (s
.verbose
> 1))
1060 // print this one manually first because it's more important than
1061 // the optional errs
1062 semantic_error
err(ERR_SRC
, _("while resolving probe point"),
1063 loc
->components
[0]->tok
, NULL
, &e
);
1066 // print optional errs accumulated while visiting other probe points
1067 for (vector
<semantic_error
>::const_iterator it
= optional_errs
.begin();
1068 it
!= optional_errs
.end(); ++it
)
1076 if (undo_parent_optional
)
1077 parent_optional
= false;
1082 // ------------------------------------------------------------------------
1084 // Indexable usage checks
1087 struct symbol_fetcher
1088 : public throwing_visitor
1092 symbol_fetcher (symbol
*&sym
): sym(sym
)
1095 void visit_symbol (symbol
* e
)
1100 void visit_arrayindex (arrayindex
* e
)
1102 e
->base
->visit (this);
1105 void throwone (const token
* t
)
1107 throw SEMANTIC_ERROR (_("Expecting symbol or array index expression"), t
);
1112 get_symbol_within_expression (expression
*e
)
1115 symbol_fetcher
fetcher(sym
);
1116 e
->visit (&fetcher
);
1117 return sym
; // NB: may be null!
1121 get_symbol_within_indexable (indexable
*ix
)
1123 symbol
*array
= NULL
;
1124 hist_op
*hist
= NULL
;
1125 classify_indexable(ix
, array
, hist
);
1129 return get_symbol_within_expression (hist
->stat
);
1132 struct mutated_var_collector
1133 : public traversing_visitor
1135 set
<vardecl
*> * mutated_vars
;
1137 mutated_var_collector (set
<vardecl
*> * mm
)
1141 void visit_assignment(assignment
* e
)
1143 if (e
->type
== pe_stats
&& e
->op
== "<<<")
1145 vardecl
*vd
= get_symbol_within_expression (e
->left
)->referent
;
1147 mutated_vars
->insert (vd
);
1149 traversing_visitor::visit_assignment(e
);
1152 void visit_arrayindex (arrayindex
*e
)
1154 if (is_active_lvalue (e
))
1157 if (e
->base
->is_symbol (sym
))
1158 mutated_vars
->insert (sym
->referent
);
1160 throw SEMANTIC_ERROR(_("Assignment to read-only histogram bucket"), e
->tok
);
1162 traversing_visitor::visit_arrayindex (e
);
1167 struct no_var_mutation_during_iteration_check
1168 : public traversing_visitor
1170 systemtap_session
& session
;
1171 map
<functiondecl
*,set
<vardecl
*> *> & function_mutates_vars
;
1172 vector
<vardecl
*> vars_being_iterated
;
1174 no_var_mutation_during_iteration_check
1175 (systemtap_session
& sess
,
1176 map
<functiondecl
*,set
<vardecl
*> *> & fmv
)
1177 : session(sess
), function_mutates_vars (fmv
)
1180 void visit_arrayindex (arrayindex
*e
)
1182 if (is_active_lvalue(e
))
1184 vardecl
*vd
= get_symbol_within_indexable (e
->base
)->referent
;
1187 for (unsigned i
= 0; i
< vars_being_iterated
.size(); ++i
)
1189 vardecl
*v
= vars_being_iterated
[i
];
1192 string err
= _F("variable '%s' modified during 'foreach' iteration",
1194 session
.print_error (SEMANTIC_ERROR (err
, e
->tok
));
1199 traversing_visitor::visit_arrayindex (e
);
1202 void visit_functioncall (functioncall
* e
)
1204 map
<functiondecl
*,set
<vardecl
*> *>::const_iterator i
1205 = function_mutates_vars
.find (e
->referent
);
1207 if (i
!= function_mutates_vars
.end())
1209 for (unsigned j
= 0; j
< vars_being_iterated
.size(); ++j
)
1211 vardecl
*m
= vars_being_iterated
[j
];
1212 if (i
->second
->find (m
) != i
->second
->end())
1214 string err
= _F("function call modifies var '%s' during 'foreach' iteration",
1216 session
.print_error (SEMANTIC_ERROR (err
, e
->tok
));
1221 traversing_visitor::visit_functioncall (e
);
1224 void visit_foreach_loop(foreach_loop
* s
)
1226 vardecl
*vd
= get_symbol_within_indexable (s
->base
)->referent
;
1229 vars_being_iterated
.push_back (vd
);
1231 traversing_visitor::visit_foreach_loop (s
);
1234 vars_being_iterated
.pop_back();
1239 // ------------------------------------------------------------------------
1241 struct stat_decl_collector
1242 : public traversing_visitor
1244 systemtap_session
& session
;
1246 stat_decl_collector(systemtap_session
& sess
)
1250 void visit_stat_op (stat_op
* e
)
1252 symbol
*sym
= get_symbol_within_expression (e
->stat
);
1253 if (session
.stat_decls
.find(sym
->name
) == session
.stat_decls
.end())
1254 session
.stat_decls
[sym
->name
] = statistic_decl();
1257 void visit_assignment (assignment
* e
)
1261 symbol
*sym
= get_symbol_within_expression (e
->left
);
1262 if (session
.stat_decls
.find(sym
->name
) == session
.stat_decls
.end())
1263 session
.stat_decls
[sym
->name
] = statistic_decl();
1266 traversing_visitor::visit_assignment(e
);
1269 void visit_hist_op (hist_op
* e
)
1271 symbol
*sym
= get_symbol_within_expression (e
->stat
);
1272 statistic_decl new_stat
;
1274 if (e
->htype
== hist_linear
)
1276 new_stat
.type
= statistic_decl::linear
;
1277 assert (e
->params
.size() == 3);
1278 new_stat
.linear_low
= e
->params
[0];
1279 new_stat
.linear_high
= e
->params
[1];
1280 new_stat
.linear_step
= e
->params
[2];
1284 assert (e
->htype
== hist_log
);
1285 new_stat
.type
= statistic_decl::logarithmic
;
1286 assert (e
->params
.size() == 0);
1289 map
<string
, statistic_decl
>::iterator i
= session
.stat_decls
.find(sym
->name
);
1290 if (i
== session
.stat_decls
.end())
1291 session
.stat_decls
[sym
->name
] = new_stat
;
1294 statistic_decl
& old_stat
= i
->second
;
1295 if (!(old_stat
== new_stat
))
1297 if (old_stat
.type
== statistic_decl::none
)
1298 i
->second
= new_stat
;
1301 // FIXME: Support multiple co-declared histogram types
1302 semantic_error
se(ERR_SRC
, _F("multiple histogram types declared on '%s'", sym
->name
.c_str()), e
->tok
);
1303 session
.print_error (se
);
1312 semantic_pass_stats (systemtap_session
& sess
)
1314 stat_decl_collector
sdc(sess
);
1316 for (map
<string
,functiondecl
*>::iterator it
= sess
.functions
.begin(); it
!= sess
.functions
.end(); it
++)
1317 it
->second
->body
->visit (&sdc
);
1319 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1320 sess
.probes
[i
]->body
->visit (&sdc
);
1322 for (unsigned i
= 0; i
< sess
.globals
.size(); ++i
)
1324 vardecl
*v
= sess
.globals
[i
];
1325 if (v
->type
== pe_stats
)
1328 if (sess
.stat_decls
.find(v
->name
) == sess
.stat_decls
.end())
1330 semantic_error
se(ERR_SRC
, _F("unable to infer statistic parameters for global '%s'", v
->name
.c_str()));
1331 sess
.print_error (se
);
1336 return sess
.num_errors();
1339 // ------------------------------------------------------------------------
1341 // Enforce variable-related invariants: no modification of
1342 // a foreach()-iterated array.
1344 semantic_pass_vars (systemtap_session
& sess
)
1347 map
<functiondecl
*, set
<vardecl
*> *> fmv
;
1348 no_var_mutation_during_iteration_check
chk(sess
, fmv
);
1350 for (map
<string
,functiondecl
*>::iterator it
= sess
.functions
.begin(); it
!= sess
.functions
.end(); it
++)
1352 functiondecl
* fn
= it
->second
;
1355 set
<vardecl
*> * m
= new set
<vardecl
*>();
1356 mutated_var_collector
mc (m
);
1357 fn
->body
->visit (&mc
);
1362 for (map
<string
,functiondecl
*>::iterator it
= sess
.functions
.begin(); it
!= sess
.functions
.end(); it
++)
1364 functiondecl
* fn
= it
->second
;
1365 if (fn
->body
) fn
->body
->visit (&chk
);
1368 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1370 if (sess
.probes
[i
]->body
)
1371 sess
.probes
[i
]->body
->visit (&chk
);
1374 return sess
.num_errors();
1378 // ------------------------------------------------------------------------
1380 // Rewrite probe condition expressions into probe bodies. Tricky and
1381 // exciting business, this. This:
1383 // probe foo if (g1 || g2) { ... }
1384 // probe bar { ... g1 ++ ... }
1388 // probe foo { if (! (g1 || g2)) next; ... }
1389 // probe bar { ... g1 ++ ...;
1390 // if (g1 || g2) %{ enable_probe_foo %} else %{ disable_probe_foo %}
1393 // In other words, we perform two transformations:
1394 // (1) Inline probe condition into its body.
1395 // (2) For each probe that modifies a global var in use in any probe's
1396 // condition, re-evaluate those probes' condition at the end of that
1399 // Here, we do all of (1), and half of (2): we simply collect the dependency
1400 // info between probes, which the translator will use to emit the affected
1401 // probes' condition re-evaluation. The translator will also ensure that the
1402 // conditions are evaluated using the globals' starting values prior to any
1405 // Adds the condition expression to the front of the probe's body
1407 derived_probe_condition_inline (derived_probe
*p
)
1409 expression
* e
= p
->sole_location()->condition
;
1412 if_statement
*ifs
= new if_statement ();
1414 ifs
->thenblock
= new next_statement ();
1415 ifs
->thenblock
->tok
= e
->tok
;
1416 ifs
->elseblock
= NULL
;
1417 unary_expression
*notex
= new unary_expression ();
1419 notex
->tok
= e
->tok
;
1421 ifs
->condition
= notex
;
1422 p
->body
= new block (ifs
, p
->body
);
1426 semantic_pass_conditions (systemtap_session
& sess
)
1428 map
<derived_probe
*, set
<vardecl
*> > vars_read_in_cond
;
1429 map
<derived_probe
*, set
<vardecl
*> > vars_written_in_body
;
1431 // do a first pass through the probes to ensure safety, inline any condition,
1432 // and collect var usage
1433 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1435 derived_probe
* p
= sess
.probes
[i
];
1436 expression
* e
= p
->sole_location()->condition
;
1440 varuse_collecting_visitor
vcv_cond(sess
);
1441 e
->visit (& vcv_cond
);
1443 if (!vcv_cond
.written
.empty())
1444 sess
.print_error (SEMANTIC_ERROR (_("probe condition must not "
1445 "modify any variables"),
1447 else if (vcv_cond
.embedded_seen
)
1448 sess
.print_error (SEMANTIC_ERROR (_("probe condition must not "
1449 "include impure embedded-C"),
1452 derived_probe_condition_inline(p
);
1454 vars_read_in_cond
[p
].insert(vcv_cond
.read
.begin(),
1455 vcv_cond
.read
.end());
1458 varuse_collecting_visitor
vcv_body(sess
);
1459 p
->body
->visit (& vcv_body
);
1461 vars_written_in_body
[p
].insert(vcv_body
.written
.begin(),
1462 vcv_body
.written
.end());
1465 // do a second pass to collect affected probes
1466 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1468 derived_probe
*p
= sess
.probes
[i
];
1470 // for each variable this probe modifies...
1471 set
<vardecl
*>::const_iterator var
;
1472 for (var
= vars_written_in_body
[p
].begin();
1473 var
!= vars_written_in_body
[p
].end(); ++var
)
1475 // collect probes which could be affected
1476 for (unsigned j
= 0; j
< sess
.probes
.size(); ++j
)
1478 if (vars_read_in_cond
[sess
.probes
[j
]].count(*var
))
1480 if (!p
->probes_with_affected_conditions
.count(sess
.probes
[j
]))
1482 p
->probes_with_affected_conditions
.insert(sess
.probes
[j
]);
1483 if (sess
.verbose
> 2)
1484 clog
<< "probe " << i
<< " can affect condition of "
1485 "probe " << j
<< endl
;
1492 return sess
.num_errors();
1495 // ------------------------------------------------------------------------
1498 // Simple visitor that just goes through all embedded code blocks that
1499 // are available at the end all the optimizations to register any
1500 // relevant pragmas or other indicators found, so that session flags can
1501 // be set that can be inspected at translation time to trigger any
1502 // necessary initialization of code needed by the embedded code functions.
1504 // This is only for pragmas that don't have any other side-effect than
1505 // needing some initialization at module init time. Currently handles
1506 // /* pragma:vma */ /* pragma:unwind */ /* pragma:symbol */
1508 // /* pragma:uprobes */ is handled during the typeresolution_info pass.
1509 // /* pure */, /* unprivileged */. /* myproc-unprivileged */ and /* guru */
1510 // are handled by the varuse_collecting_visitor.
1512 struct embeddedcode_info
: public functioncall_traversing_visitor
1515 systemtap_session
& session
;
1518 embeddedcode_info (systemtap_session
& s
): session(s
) { }
1520 void visit_embeddedcode (embeddedcode
* c
)
1522 if (! vma_tracker_enabled(session
)
1523 && c
->code
.find("/* pragma:vma */") != string::npos
)
1525 if (session
.verbose
> 2)
1526 clog
<< _F("Turning on task_finder vma_tracker, pragma:vma found in %s",
1527 current_function
->name
.c_str()) << endl
;
1529 // PR15052: stapdyn doesn't have VMA-tracking yet.
1530 if (session
.runtime_usermode_p())
1531 throw SEMANTIC_ERROR(_("VMA-tracking is only supported by the kernel runtime (PR15052)"), c
->tok
);
1533 enable_vma_tracker(session
);
1536 if (! session
.need_unwind
1537 && c
->code
.find("/* pragma:unwind */") != string::npos
)
1539 if (session
.verbose
> 2)
1540 clog
<< _F("Turning on unwind support, pragma:unwind found in %s",
1541 current_function
->name
.c_str()) << endl
;
1542 session
.need_unwind
= true;
1545 if (! session
.need_symbols
1546 && c
->code
.find("/* pragma:symbols */") != string::npos
)
1548 if (session
.verbose
> 2)
1549 clog
<< _F("Turning on symbol data collecting, pragma:symbols found in %s",
1550 current_function
->name
.c_str()) << endl
;
1551 session
.need_symbols
= true;
1556 void embeddedcode_info_pass (systemtap_session
& s
)
1558 embeddedcode_info
eci (s
);
1559 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
1560 s
.probes
[i
]->body
->visit (& eci
);
1563 // ------------------------------------------------------------------------
1566 // Simple visitor that collects all the regular expressions in the
1567 // file and adds them to the session DFA table.
1569 struct regex_collecting_visitor
: public functioncall_traversing_visitor
1572 systemtap_session
& session
;
1575 regex_collecting_visitor (systemtap_session
& s
): session(s
) { }
1577 void visit_regex_query (regex_query
*q
) {
1578 functioncall_traversing_visitor::visit_regex_query (q
);
1580 string re
= q
->right
->value
;
1581 regex_to_stapdfa (&session
, re
, q
->right
->tok
);
1585 // Go through the regex match invocations and generate corresponding DFAs.
1586 int gen_dfa_table (systemtap_session
& s
)
1588 regex_collecting_visitor
rcv(s
);
1590 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
1594 s
.probes
[i
]->body
->visit (& rcv
);
1596 if (s
.probes
[i
]->sole_location()->condition
)
1597 s
.probes
[i
]->sole_location()->condition
->visit (& rcv
);
1599 catch (const semantic_error
& e
)
1605 return s
.num_errors();
1608 // ------------------------------------------------------------------------
1611 static int semantic_pass_symbols (systemtap_session
&);
1612 static int semantic_pass_optimize1 (systemtap_session
&);
1613 static int semantic_pass_optimize2 (systemtap_session
&);
1614 static int semantic_pass_types (systemtap_session
&);
1615 static int semantic_pass_vars (systemtap_session
&);
1616 static int semantic_pass_stats (systemtap_session
&);
1617 static int semantic_pass_conditions (systemtap_session
&);
1620 struct expression_build_no_more_visitor
: public expression_visitor
1622 // Clear extra details from every expression, like DWARF type info, so that
1623 // builders can safely release them in build_no_more. From here on out,
1624 // we're back to basic types only.
1625 void visit_expression(expression
*e
)
1627 e
->type_details
.reset();
1632 build_no_more (systemtap_session
& s
)
1634 expression_build_no_more_visitor v
;
1636 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
1637 s
.probes
[i
]->body
->visit(&v
);
1639 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
1640 it
!= s
.functions
.end(); it
++)
1641 it
->second
->body
->visit(&v
);
1643 // Inform all derived_probe builders that we're done with
1644 // all resolution, so it's time to release caches.
1645 s
.pattern_root
->build_no_more (s
);
1650 // Link up symbols to their declarations. Set the session's
1651 // files/probes/functions/globals vectors from the transitively
1652 // reached set of stapfiles in s.library_files, starting from
1653 // s.user_file. Perform automatic tapset inclusion and probe
1656 semantic_pass_symbols (systemtap_session
& s
)
1658 symresolution_info
sym (s
);
1660 // If we're listing functions, then we need to include all the files. Probe
1661 // aliases won't be visited/derived so all we gain are the functions, global
1662 // variables, and any real probes (e.g. begin probes). NB: type resolution for
1663 // a specific function arg may fail if it could only be determined from a
1664 // function call in one of the skipped aliases.
1665 if (s
.dump_mode
== systemtap_session::dump_functions
)
1667 s
.files
.insert(s
.files
.end(), s
.library_files
.begin(),
1668 s
.library_files
.end());
1670 else if (!s
.user_files
.empty())
1672 // Normal run: seed s.files with user_files and let it grow through the
1673 // find_* functions. NB: s.files can grow during this iteration, so
1674 // size() can return gradually increasing numbers.
1675 s
.files
.insert (s
.files
.end(), s
.user_files
.begin(), s
.user_files
.end());
1678 for (unsigned i
= 0; i
< s
.files
.size(); i
++)
1680 assert_no_interrupts();
1681 stapfile
* dome
= s
.files
[i
];
1683 // Pass 1: add globals and functions to systemtap-session master list,
1684 // so the find_* functions find them
1686 // NB: tapset global/function definitions may duplicate or conflict
1687 // with those already in s.globals/functions. We need to deconflict
1690 for (unsigned i
=0; i
<dome
->globals
.size(); i
++)
1692 vardecl
* g
= dome
->globals
[i
];
1693 for (unsigned j
=0; j
<s
.globals
.size(); j
++)
1695 vardecl
* g2
= s
.globals
[j
];
1696 if (g
->name
== g2
->name
)
1698 s
.print_error (SEMANTIC_ERROR (_("conflicting global variables"),
1702 s
.globals
.push_back (g
);
1705 for (unsigned i
=0; i
<dome
->functions
.size(); i
++)
1707 functiondecl
* f
= dome
->functions
[i
];
1708 functiondecl
* f2
= s
.functions
[f
->name
];
1711 s
.print_error (SEMANTIC_ERROR (_("conflicting functions"),
1714 s
.functions
[f
->name
] = f
;
1717 // NB: embeds don't conflict with each other
1718 for (unsigned i
=0; i
<dome
->embeds
.size(); i
++)
1719 s
.embeds
.push_back (dome
->embeds
[i
]);
1721 // Pass 2: derive probes and resolve any further symbols in the
1724 for (unsigned i
=0; i
<dome
->probes
.size(); i
++)
1726 assert_no_interrupts();
1727 probe
* p
= dome
->probes
[i
];
1728 vector
<derived_probe
*> dps
;
1730 // much magic happens here: probe alias expansion, wildcard
1731 // matching, low-level derived_probe construction.
1732 derive_probes (s
, p
, dps
);
1734 for (unsigned j
=0; j
<dps
.size(); j
++)
1736 assert_no_interrupts();
1737 derived_probe
* dp
= dps
[j
];
1738 s
.probes
.push_back (dp
);
1743 for (unsigned k
=0; k
<s
.code_filters
.size(); k
++)
1744 s
.code_filters
[k
]->replace (dp
->body
);
1746 sym
.current_function
= 0;
1747 sym
.current_probe
= dp
;
1748 dp
->body
->visit (& sym
);
1750 // Process the probe-point condition expression.
1751 sym
.current_function
= 0;
1752 sym
.current_probe
= 0;
1753 if (dp
->sole_location()->condition
)
1754 dp
->sole_location()->condition
->visit (& sym
);
1756 catch (const semantic_error
& e
)
1763 // Pass 3: process functions
1765 for (unsigned i
=0; i
<dome
->functions
.size(); i
++)
1767 assert_no_interrupts();
1768 functiondecl
* fd
= dome
->functions
[i
];
1772 for (unsigned j
=0; j
<s
.code_filters
.size(); j
++)
1773 s
.code_filters
[j
]->replace (fd
->body
);
1775 sym
.current_function
= fd
;
1776 sym
.current_probe
= 0;
1777 fd
->body
->visit (& sym
);
1779 catch (const semantic_error
& e
)
1786 if(s
.systemtap_v_check
){
1787 for(unsigned i
=0;i
<s
.globals
.size();i
++){
1788 if(s
.globals
[i
]->systemtap_v_conditional
)
1789 s
.print_warning(_("This global uses tapset constructs that are dependent on systemtap version"), s
.globals
[i
]->tok
);
1792 for(map
<string
, functiondecl
*>::const_iterator i
=s
.functions
.begin();i
!= s
.functions
.end();++i
){
1793 if(i
->second
->systemtap_v_conditional
)
1794 s
.print_warning(_("This function uses tapset constructs that are dependent on systemtap version"), i
->second
->tok
);
1797 for(unsigned i
=0;i
<s
.probes
.size();i
++){
1798 vector
<probe
*> sysvc
;
1799 s
.probes
[i
]->collect_derivation_chain(sysvc
);
1800 for(unsigned j
=0;j
<sysvc
.size();j
++){
1801 if(sysvc
[j
]->systemtap_v_conditional
)
1802 s
.print_warning(_("This probe uses tapset constructs that are dependent on systemtap version"), sysvc
[j
]->tok
);
1803 if(sysvc
[j
]->get_alias() && sysvc
[j
]->get_alias()->systemtap_v_conditional
)
1804 s
.print_warning(_("This alias uses tapset constructs that are dependent on systemtap version"), sysvc
[j
]->get_alias()->tok
);
1809 return s
.num_errors(); // all those print_error calls
1813 // Keep unread global variables for probe end value display.
1814 void add_global_var_display (systemtap_session
& s
)
1816 // Don't generate synthetic end probes when in listing mode; it would clutter
1817 // up the list of probe points with "end ...". In fact, don't bother in any
1818 // dump mode at all, since it'll never be used.
1819 if (s
.dump_mode
) return;
1821 varuse_collecting_visitor
vut(s
);
1823 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
1825 s
.probes
[i
]->body
->visit (& vut
);
1827 if (s
.probes
[i
]->sole_location()->condition
)
1828 s
.probes
[i
]->sole_location()->condition
->visit (& vut
);
1831 for (unsigned g
=0; g
< s
.globals
.size(); g
++)
1833 vardecl
* l
= s
.globals
[g
];
1834 if ((vut
.read
.find (l
) != vut
.read
.end()
1835 && vut
.used
.find (l
) != vut
.used
.end())
1836 || vut
.written
.find (l
) == vut
.written
.end())
1839 // Don't generate synthetic end probes for unread globals
1840 // declared only within tapsets. (RHBZ 468139), but rather
1841 // only within the end-user script.
1843 bool tapset_global
= false;
1844 for (size_t m
=0; m
< s
.library_files
.size(); m
++)
1846 for (size_t n
=0; n
< s
.library_files
[m
]->globals
.size(); n
++)
1848 if (l
->name
== s
.library_files
[m
]->globals
[n
]->name
)
1849 {tapset_global
= true; break;}
1856 code
<< "probe end {" << endl
;
1858 string format
= l
->name
;
1861 string foreach_value
;
1862 if (!l
->index_types
.empty())
1864 // Add index values to the printf format, and prepare
1865 // a simple list of indexes for passing around elsewhere
1867 for (size_t i
= 0; i
< l
->index_types
.size(); ++i
)
1874 indexes
+= "__idx" + lex_cast(i
);
1875 if (l
->index_types
[i
] == pe_string
)
1876 format
+= "\\\"%#s\\\"";
1882 // Iterate over all indexes in the array, sorted by decreasing value
1883 code
<< "foreach (";
1884 if (l
->type
!= pe_stats
)
1886 foreach_value
= "__val";
1887 code
<< foreach_value
<< " = ";
1889 code
<< "[" << indexes
<< "] in " << l
->name
<< "-)" << endl
;
1891 else if (l
->type
== pe_stats
)
1893 // PR7053: Check scalar globals for empty aggregate
1894 code
<< "if (@count(" << l
->name
<< ") == 0)" << endl
;
1895 code
<< "printf(\"" << l
->name
<< " @count=0x0\\n\")" << endl
;
1896 code
<< "else" << endl
;
1899 static const string stats
[] = { "@count", "@min", "@max", "@sum", "@avg" };
1900 const string stats_format
=
1901 (strverscmp(s
.compatible
.c_str(), "1.4") >= 0) ? "%#d" : "%#x";
1903 // Fill in the printf format for values
1904 if (l
->type
== pe_stats
)
1905 for (size_t i
= 0; i
< sizeof(stats
)/sizeof(stats
[0]); ++i
)
1906 format
+= " " + stats
[i
] + "=" + stats_format
;
1907 else if (l
->type
== pe_string
)
1908 format
+= "=\\\"%#s\\\"";
1913 // Output the actual printf
1914 code
<< "printf (\"" << format
<< "\"";
1916 // Feed indexes to the printf, and include them in the value
1917 string value
= !foreach_value
.empty() ? foreach_value
: l
->name
;
1918 if (!l
->index_types
.empty())
1920 code
<< "," << indexes
;
1921 if (foreach_value
.empty())
1922 value
+= "[" + indexes
+ "]";
1925 // Feed the actual values to the printf
1926 if (l
->type
== pe_stats
)
1927 for (size_t i
= 0; i
< sizeof(stats
)/sizeof(stats
[0]); ++i
)
1928 code
<< "," << stats
[i
] << "(" << value
<< ")";
1930 code
<< "," << value
;
1931 code
<< ")" << endl
;
1934 code
<< "}" << endl
;
1936 probe
*p
= parse_synthetic_probe (s
, code
, l
->tok
);
1938 throw SEMANTIC_ERROR (_("can't create global var display"), l
->tok
);
1940 vector
<derived_probe
*> dps
;
1941 derive_probes (s
, p
, dps
);
1942 for (unsigned i
= 0; i
< dps
.size(); i
++)
1944 derived_probe
* dp
= dps
[i
];
1945 s
.probes
.push_back (dp
);
1948 // Repopulate symbol and type info
1949 symresolution_info
sym (s
);
1950 sym
.current_function
= 0;
1951 sym
.current_probe
= dp
;
1952 dp
->body
->visit (& sym
);
1955 semantic_pass_types(s
);
1956 // Mark that variable is read
1957 vut
.read
.insert (l
);
1962 semantic_pass (systemtap_session
& s
)
1968 s
.register_library_aliases();
1969 register_standard_tapsets(s
);
1971 if (rc
== 0) rc
= semantic_pass_symbols (s
);
1972 if (rc
== 0) rc
= semantic_pass_conditions (s
);
1973 if (rc
== 0) rc
= semantic_pass_optimize1 (s
);
1974 if (rc
== 0) rc
= semantic_pass_types (s
);
1975 if (rc
== 0) rc
= gen_dfa_table(s
);
1976 if (rc
== 0) add_global_var_display (s
);
1977 if (rc
== 0) rc
= semantic_pass_optimize2 (s
);
1978 if (rc
== 0) rc
= semantic_pass_vars (s
);
1979 if (rc
== 0) rc
= semantic_pass_stats (s
);
1980 if (rc
== 0) embeddedcode_info_pass (s
);
1982 catch (const semantic_error
& e
)
1988 bool no_primary_probes
= true;
1989 for (unsigned i
= 0; i
< s
.probes
.size(); i
++)
1990 if (s
.is_primary_probe(s
.probes
[i
]))
1991 no_primary_probes
= false;
1993 if (s
.num_errors() == 0 && no_primary_probes
&& !s
.dump_mode
)
1995 s
.print_error(SEMANTIC_ERROR(_("no probes found")));
2002 // NB: listing mode only cares whether we have any probes,
2003 // so all previous error conditions are disregarded.
2004 if (s
.dump_mode
== systemtap_session::dump_matched_probes
||
2005 s
.dump_mode
== systemtap_session::dump_matched_probes_vars
)
2006 rc
= no_primary_probes
;
2008 // If we're dumping functions, only error out if no functions were found
2009 if (s
.dump_mode
== systemtap_session::dump_functions
)
2010 rc
= s
.functions
.empty();
2016 // ------------------------------------------------------------------------
2017 // semantic processing: symbol resolution
2020 symresolution_info::symresolution_info (systemtap_session
& s
):
2021 session (s
), current_function (0), current_probe (0)
2027 symresolution_info::visit_block (block
* e
)
2029 for (unsigned i
=0; i
<e
->statements
.size(); i
++)
2033 e
->statements
[i
]->visit (this);
2035 catch (const semantic_error
& e
)
2037 session
.print_error (e
);
2044 symresolution_info::visit_foreach_loop (foreach_loop
* e
)
2046 for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
2047 e
->indexes
[i
]->visit (this);
2048 for (unsigned i
=0; i
<e
->array_slice
.size(); i
++)
2049 if (e
->array_slice
[i
])
2050 e
->array_slice
[i
]->visit(this);
2052 symbol
*array
= NULL
;
2053 hist_op
*hist
= NULL
;
2054 classify_indexable (e
->base
, array
, hist
);
2058 if (!array
->referent
)
2060 vardecl
* d
= find_var (array
->name
, e
->indexes
.size (), array
->tok
);
2062 array
->referent
= d
;
2066 msg
<< _F("unresolved arity-%zu global array %s, missing global declaration?",
2067 e
->indexes
.size(), array
->name
.c_str());
2068 throw SEMANTIC_ERROR (msg
.str(), array
->tok
);
2072 if (!e
->array_slice
.empty() && e
->array_slice
.size() != e
->indexes
.size())
2075 msg
<< _F("unresolved arity-%zu global array %s, missing global declaration?",
2076 e
->array_slice
.size(), array
->name
.c_str());
2077 throw SEMANTIC_ERROR (msg
.str(), array
->tok
);
2087 e
->value
->visit (this);
2090 e
->limit
->visit (this);
2092 e
->block
->visit (this);
2097 delete_statement_symresolution_info
:
2098 public traversing_visitor
2100 symresolution_info
*parent
;
2102 delete_statement_symresolution_info (symresolution_info
*p
):
2106 void visit_arrayindex (arrayindex
* e
)
2108 parent
->visit_arrayindex(e
, true);
2111 void visit_functioncall (functioncall
* e
)
2113 parent
->visit_functioncall (e
);
2116 void visit_symbol (symbol
* e
)
2121 vardecl
* d
= parent
->find_var (e
->name
, -1, e
->tok
);
2125 throw SEMANTIC_ERROR (_("unresolved array in delete statement"), e
->tok
);
2130 symresolution_info::visit_delete_statement (delete_statement
* s
)
2132 delete_statement_symresolution_info
di (this);
2133 s
->value
->visit (&di
);
2138 symresolution_info::visit_symbol (symbol
* e
)
2143 vardecl
* d
= find_var (e
->name
, 0, e
->tok
);
2149 vardecl
* v
= new vardecl
;
2152 v
->set_arity(0, e
->tok
);
2153 if (current_function
)
2154 current_function
->locals
.push_back (v
);
2155 else if (current_probe
)
2156 current_probe
->locals
.push_back (v
);
2158 // must be probe-condition expression
2159 throw SEMANTIC_ERROR (_("probe condition must not reference undeclared global"), e
->tok
);
2166 symresolution_info::visit_arrayindex (arrayindex
* e
)
2168 visit_arrayindex(e
, false);
2172 symresolution_info::visit_arrayindex (arrayindex
* e
, bool wildcard_ok
)
2174 for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
2176 // assuming that if NULL, it was originally a wildcard (*)
2177 if (e
->indexes
[i
] == NULL
)
2180 throw SEMANTIC_ERROR(_("wildcard not allowed in array index"), e
->tok
);
2183 e
->indexes
[i
]->visit (this);
2186 symbol
*array
= NULL
;
2187 hist_op
*hist
= NULL
;
2188 classify_indexable(e
->base
, array
, hist
);
2192 if (array
->referent
)
2195 vardecl
* d
= find_var (array
->name
, e
->indexes
.size (), array
->tok
);
2197 array
->referent
= d
;
2201 msg
<< _F("unresolved arity-%zu global array %s, missing global declaration?",
2202 e
->indexes
.size(), array
->name
.c_str());
2203 throw SEMANTIC_ERROR (msg
.str(), e
->tok
);
2215 symresolution_info::visit_array_in (array_in
* e
)
2217 visit_arrayindex(e
->operand
, true);
2222 symresolution_info::visit_functioncall (functioncall
* e
)
2224 // XXX: we could relax this, if we're going to examine the
2225 // vartracking data recursively. See testsuite/semko/fortytwo.stp.
2226 if (! (current_function
|| current_probe
))
2228 // must be probe-condition expression
2229 throw SEMANTIC_ERROR (_("probe condition must not reference function"), e
->tok
);
2232 for (unsigned i
=0; i
<e
->args
.size(); i
++)
2233 e
->args
[i
]->visit (this);
2238 functiondecl
* d
= find_function (e
->function
, e
->args
.size (), e
->tok
);
2243 string sugs
= levenshtein_suggest(e
->function
, collect_functions(), 5); // print 5 funcs
2244 throw SEMANTIC_ERROR(_F("unresolved function%s",
2245 sugs
.empty() ? "" : (_(" (similar: ") + sugs
+ ")").c_str()),
2250 /*find_var will return an argument other than zero if the name matches the var
2251 * name ie, if the current local name matches the name passed to find_var*/
2253 symresolution_info::find_var (const string
& name
, int arity
, const token
* tok
)
2255 if (current_function
|| current_probe
)
2258 vector
<vardecl
*>& locals
= (current_function
?
2259 current_function
->locals
:
2260 current_probe
->locals
);
2263 for (unsigned i
=0; i
<locals
.size(); i
++)
2264 if (locals
[i
]->name
== name
)
2266 locals
[i
]->set_arity (arity
, tok
);
2271 // search function formal parameters (for scalars)
2272 if (arity
== 0 && current_function
)
2273 for (unsigned i
=0; i
<current_function
->formal_args
.size(); i
++)
2274 if (current_function
->formal_args
[i
]->name
== name
)
2276 // NB: no need to check arity here: formal args always scalar
2277 current_function
->formal_args
[i
]->set_arity (0, tok
);
2278 return current_function
->formal_args
[i
];
2281 // search processed globals
2282 for (unsigned i
=0; i
<session
.globals
.size(); i
++)
2283 if (session
.globals
[i
]->name
== name
)
2285 if (! session
.suppress_warnings
)
2287 vardecl
* v
= session
.globals
[i
];
2288 stapfile
* f
= tok
->location
.file
;
2289 // clog << "resolved " << *tok << " to global " << *v->tok << endl;
2290 if (v
->tok
->location
.file
!= f
&& !f
->synthetic
)
2292 session
.print_warning (_F("cross-file global variable reference to %s from",
2293 lex_cast(*v
->tok
).c_str()), tok
);
2296 session
.globals
[i
]->set_arity (arity
, tok
);
2297 return session
.globals
[i
];
2300 // search library globals
2301 for (unsigned i
=0; i
<session
.library_files
.size(); i
++)
2303 stapfile
* f
= session
.library_files
[i
];
2304 for (unsigned j
=0; j
<f
->globals
.size(); j
++)
2306 vardecl
* g
= f
->globals
[j
];
2307 if (g
->name
== name
)
2309 g
->set_arity (arity
, tok
);
2311 // put library into the queue if not already there
2312 if (find (session
.files
.begin(), session
.files
.end(), f
)
2313 == session
.files
.end())
2314 session
.files
.push_back (f
);
2326 symresolution_info::find_function (const string
& name
, unsigned arity
, const token
*tok
)
2329 if (session
.functions
.find(name
) != session
.functions
.end())
2331 functiondecl
* fd
= session
.functions
[name
];
2332 assert (fd
->name
== name
);
2333 if (fd
->formal_args
.size() == arity
)
2336 throw SEMANTIC_ERROR(_F("arity mismatch found (function '%s' takes %zu args)",
2337 name
.c_str(), fd
->formal_args
.size()), tok
, fd
->tok
);
2340 // search library functions
2341 for (unsigned i
=0; i
<session
.library_files
.size(); i
++)
2343 stapfile
* f
= session
.library_files
[i
];
2344 for (unsigned j
=0; j
<f
->functions
.size(); j
++)
2345 if (f
->functions
[j
]->name
== name
)
2347 if (f
->functions
[j
]->formal_args
.size() == arity
)
2349 // put library into the queue if not already there
2350 if (0) // session.verbose_resolution
2351 cerr
<< _F(" function %s is defined from %s",
2352 name
.c_str(), f
->name
.c_str()) << endl
;
2354 if (find (session
.files
.begin(), session
.files
.end(), f
)
2355 == session
.files
.end())
2356 session
.files
.push_back (f
);
2357 // else .. print different message?
2359 return f
->functions
[j
];
2362 throw SEMANTIC_ERROR(_F("arity mismatch found (function '%s' takes %zu args)",
2363 name
.c_str(), f
->functions
[j
]->formal_args
.size()),
2364 tok
, f
->functions
[j
]->tok
);
2372 symresolution_info::collect_functions(void)
2376 for (map
<string
,functiondecl
*>::const_iterator it
= session
.functions
.begin();
2377 it
!= session
.functions
.end(); ++it
)
2378 funcs
.insert(it
->first
);
2380 // search library functions
2381 for (unsigned i
=0; i
<session
.library_files
.size(); i
++)
2383 stapfile
* f
= session
.library_files
[i
];
2384 for (unsigned j
=0; j
<f
->functions
.size(); j
++)
2385 funcs
.insert(f
->functions
[j
]->name
);
2391 // ------------------------------------------------------------------------
2395 // Do away with functiondecls that are never (transitively) called
2397 void semantic_pass_opt1 (systemtap_session
& s
, bool& relaxed_p
)
2399 functioncall_traversing_visitor ftv
;
2400 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
2402 s
.probes
[i
]->body
->visit (& ftv
);
2403 if (s
.probes
[i
]->sole_location()->condition
)
2404 s
.probes
[i
]->sole_location()->condition
->visit (& ftv
);
2406 vector
<functiondecl
*> new_unused_functions
;
2407 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
2409 functiondecl
* fd
= it
->second
;
2410 if (ftv
.seen
.find(fd
) == ftv
.seen
.end())
2412 if (! fd
->synthetic
&& s
.is_user_file(fd
->tok
->location
.file
->name
))
2413 s
.print_warning (_F("Eliding unused function '%s'", fd
->name
.c_str()), fd
->tok
);
2414 // s.functions.erase (it); // NB: can't, since we're already iterating upon it
2415 new_unused_functions
.push_back (fd
);
2419 for (unsigned i
=0; i
<new_unused_functions
.size(); i
++)
2421 map
<string
,functiondecl
*>::iterator where
= s
.functions
.find (new_unused_functions
[i
]->name
);
2422 assert (where
!= s
.functions
.end());
2423 s
.functions
.erase (where
);
2424 if (s
.tapset_compile_coverage
)
2425 s
.unused_functions
.push_back (new_unused_functions
[i
]);
2430 // ------------------------------------------------------------------------
2432 // Do away with local & global variables that are never
2433 // written nor read.
2434 void semantic_pass_opt2 (systemtap_session
& s
, bool& relaxed_p
, unsigned iterations
)
2436 varuse_collecting_visitor
vut(s
);
2438 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
2440 s
.probes
[i
]->body
->visit (& vut
);
2442 if (s
.probes
[i
]->sole_location()->condition
)
2443 s
.probes
[i
]->sole_location()->condition
->visit (& vut
);
2446 // NB: Since varuse_collecting_visitor also traverses down
2447 // actually called functions, we don't need to explicitly
2448 // iterate over them. Uncalled ones should have been pruned
2451 // for (unsigned i=0; i<s.functions.size(); i++)
2452 // s.functions[i]->body->visit (& vut);
2454 // Now in vut.read/written, we have a mixture of all locals, globals
2456 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
2457 for (unsigned j
=0; j
<s
.probes
[i
]->locals
.size(); /* see below */)
2459 vardecl
* l
= s
.probes
[i
]->locals
[j
];
2461 // skip over "special" locals
2462 if (l
->synthetic
) { j
++; continue; }
2464 if (vut
.read
.find (l
) == vut
.read
.end() &&
2465 vut
.written
.find (l
) == vut
.written
.end())
2467 if (s
.is_user_file(l
->tok
->location
.file
->name
))
2468 s
.print_warning (_F("Eliding unused variable '%s'", l
->name
.c_str()), l
->tok
);
2469 if (s
.tapset_compile_coverage
) {
2470 s
.probes
[i
]->unused_locals
.push_back
2471 (s
.probes
[i
]->locals
[j
]);
2473 s
.probes
[i
]->locals
.erase(s
.probes
[i
]->locals
.begin() + j
);
2475 // don't increment j
2479 if (vut
.written
.find (l
) == vut
.written
.end())
2480 if (iterations
== 0 && ! s
.suppress_warnings
)
2483 vector
<vardecl
*>::iterator it
;
2484 for (it
= s
.probes
[i
]->locals
.begin(); it
!= s
.probes
[i
]->locals
.end(); it
++)
2485 vars
.insert((*it
)->name
);
2486 for (it
= s
.globals
.begin(); it
!= s
.globals
.end(); it
++)
2487 vars
.insert((*it
)->name
);
2489 vars
.erase(l
->name
);
2490 string sugs
= levenshtein_suggest(l
->name
, vars
, 5); // suggest top 5 vars
2491 s
.print_warning (_F("never-assigned local variable '%s'%s",
2492 l
->name
.c_str(), (sugs
.empty() ? "" :
2493 (_(" (similar: ") + sugs
+ ")")).c_str()), l
->tok
);
2499 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
2501 functiondecl
*fd
= it
->second
;
2502 for (unsigned j
=0; j
<fd
->locals
.size(); /* see below */)
2504 vardecl
* l
= fd
->locals
[j
];
2505 if (vut
.read
.find (l
) == vut
.read
.end() &&
2506 vut
.written
.find (l
) == vut
.written
.end())
2508 if (s
.is_user_file(l
->tok
->location
.file
->name
))
2509 s
.print_warning (_F("Eliding unused variable '%s'", l
->name
.c_str()), l
->tok
);
2510 if (s
.tapset_compile_coverage
) {
2511 fd
->unused_locals
.push_back (fd
->locals
[j
]);
2513 fd
->locals
.erase(fd
->locals
.begin() + j
);
2515 // don't increment j
2519 if (vut
.written
.find (l
) == vut
.written
.end())
2520 if (iterations
== 0 && ! s
.suppress_warnings
)
2523 vector
<vardecl
*>::iterator it
;
2524 for (it
= fd
->formal_args
.begin() ;
2525 it
!= fd
->formal_args
.end(); it
++)
2526 vars
.insert((*it
)->name
);
2527 for (it
= fd
->locals
.begin(); it
!= fd
->locals
.end(); it
++)
2528 vars
.insert((*it
)->name
);
2529 for (it
= s
.globals
.begin(); it
!= s
.globals
.end(); it
++)
2530 vars
.insert((*it
)->name
);
2532 vars
.erase(l
->name
);
2533 string sugs
= levenshtein_suggest(l
->name
, vars
, 5); // suggest top 5 vars
2534 s
.print_warning (_F("never-assigned local variable '%s'%s",
2535 l
->name
.c_str(), (sugs
.empty() ? "" :
2536 (_(" (similar: ") + sugs
+ ")")).c_str()), l
->tok
);
2543 for (unsigned i
=0; i
<s
.globals
.size(); /* see below */)
2545 vardecl
* l
= s
.globals
[i
];
2546 if (vut
.read
.find (l
) == vut
.read
.end() &&
2547 vut
.written
.find (l
) == vut
.written
.end())
2549 if (s
.is_user_file(l
->tok
->location
.file
->name
))
2550 s
.print_warning (_F("Eliding unused variable '%s'", l
->name
.c_str()), l
->tok
);
2551 if (s
.tapset_compile_coverage
) {
2552 s
.unused_globals
.push_back(s
.globals
[i
]);
2554 s
.globals
.erase(s
.globals
.begin() + i
);
2556 // don't increment i
2560 if (vut
.written
.find (l
) == vut
.written
.end() && ! l
->init
) // no initializer
2561 if (iterations
== 0 && ! s
.suppress_warnings
)
2564 vector
<vardecl
*>::iterator it
;
2565 for (it
= s
.globals
.begin(); it
!= s
.globals
.end(); it
++)
2566 if (l
->name
!= (*it
)->name
)
2567 vars
.insert((*it
)->name
);
2569 string sugs
= levenshtein_suggest(l
->name
, vars
, 5); // suggest top 5 vars
2570 s
.print_warning (_F("never-assigned global variable '%s'%s",
2571 l
->name
.c_str(), (sugs
.empty() ? "" :
2572 (_(" (similar: ") + sugs
+ ")")).c_str()), l
->tok
);
2581 // ------------------------------------------------------------------------
2583 struct dead_assignment_remover
: public update_visitor
2585 systemtap_session
& session
;
2587 const varuse_collecting_visitor
& vut
;
2589 dead_assignment_remover(systemtap_session
& s
, bool& r
,
2590 const varuse_collecting_visitor
& v
):
2591 session(s
), relaxed_p(r
), vut(v
) {}
2593 void visit_assignment (assignment
* e
);
2594 void visit_try_block (try_block
*s
);
2598 // symbol_fetcher augmented to allow target-symbol types, but NULLed.
2599 struct assignment_symbol_fetcher
2600 : public symbol_fetcher
2602 assignment_symbol_fetcher (symbol
*&sym
): symbol_fetcher(sym
)
2605 void visit_target_symbol (target_symbol
* e
)
2610 void visit_atvar_op (atvar_op
*e
)
2615 void visit_cast_op (cast_op
* e
)
2620 void visit_autocast_op (autocast_op
* e
)
2625 void throwone (const token
* t
)
2627 if (t
->type
== tok_operator
&& t
->content
== ".")
2628 // guess someone misused . in $foo->bar.baz expression
2629 // XXX why are we only checking this in lvalues?
2630 throw SEMANTIC_ERROR (_("Expecting lvalue expression, try -> instead"), t
);
2632 throw SEMANTIC_ERROR (_("Expecting lvalue expression"), t
);
2637 get_assignment_symbol_within_expression (expression
*e
)
2640 assignment_symbol_fetcher
fetcher(sym
);
2641 e
->visit (&fetcher
);
2642 return sym
; // NB: may be null!
2647 dead_assignment_remover::visit_assignment (assignment
* e
)
2652 symbol
* left
= get_assignment_symbol_within_expression (e
->left
);
2653 if (left
) // not unresolved $target, so intended sideeffect may be elided
2655 vardecl
* leftvar
= left
->referent
;
2656 if (vut
.read
.find(leftvar
) == vut
.read
.end()) // var never read?
2658 // NB: Not so fast! The left side could be an array whose
2659 // index expressions may have side-effects. This would be
2660 // OK if we could replace the array assignment with a
2661 // statement-expression containing all the index expressions
2662 // and the rvalue... but we can't.
2663 // Another possibility is that we have an unread global variable
2664 // which are kept for probe end value display.
2666 bool is_global
= false;
2667 vector
<vardecl
*>::iterator it
;
2668 for (it
= session
.globals
.begin(); it
!= session
.globals
.end(); it
++)
2669 if (leftvar
->name
== (*it
)->name
)
2675 varuse_collecting_visitor
lvut(session
);
2676 e
->left
->visit (& lvut
);
2677 if (lvut
.side_effect_free () && !is_global
// XXX: use _wrt() once we track focal_vars
2678 && !leftvar
->synthetic
) // don't elide assignment to synthetic $context variables
2680 /* PR 1119: NB: This is not necessary here. A write-only
2681 variable will also be elided soon at the next _opt2 iteration.
2682 if (e->left->tok->location.file->name == session.user_file->name) // !tapset
2683 session.print_warning("eliding write-only ", *e->left->tok);
2686 if (session
.is_user_file(e
->left
->tok
->location
.file
->name
))
2687 session
.print_warning(_F("Eliding assignment to '%s'", leftvar
->name
.c_str()), e
->tok
);
2688 provide (e
->right
); // goodbye assignment*
2699 dead_assignment_remover::visit_try_block (try_block
*s
)
2701 replace (s
->try_block
);
2702 if (s
->catch_error_var
)
2704 vardecl
* errvar
= s
->catch_error_var
->referent
;
2705 if (vut
.read
.find(errvar
) == vut
.read
.end()) // never read?
2707 if (session
.verbose
>2)
2708 clog
<< _F("Eliding unused error string catcher %s at %s",
2709 errvar
->name
.c_str(), lex_cast(*s
->tok
).c_str()) << endl
;
2710 s
->catch_error_var
= 0;
2713 replace (s
->catch_block
);
2718 // Let's remove assignments to variables that are never read. We
2719 // rewrite "(foo = expr)" as "(expr)". This makes foo a candidate to
2720 // be optimized away as an unused variable, and expr a candidate to be
2721 // removed as a side-effect-free statement expression. Wahoo!
2722 void semantic_pass_opt3 (systemtap_session
& s
, bool& relaxed_p
)
2724 // Recompute the varuse data, which will probably match the opt2
2725 // copy of the computation, except for those totally unused
2726 // variables that opt2 removed.
2727 varuse_collecting_visitor
vut(s
);
2728 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
2729 s
.probes
[i
]->body
->visit (& vut
); // includes reachable functions too
2731 dead_assignment_remover
dar (s
, relaxed_p
, vut
);
2732 // This instance may be reused for multiple probe/function body trims.
2734 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
2735 dar
.replace (s
.probes
[i
]->body
);
2736 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
2737 it
!= s
.functions
.end(); it
++)
2738 dar
.replace (it
->second
->body
);
2739 // The rewrite operation is performed within the visitor.
2741 // XXX: we could also zap write-only globals here
2745 // ------------------------------------------------------------------------
2747 struct dead_stmtexpr_remover
: public update_visitor
2749 systemtap_session
& session
;
2751 set
<vardecl
*> focal_vars
; // vars considered subject to side-effects
2753 dead_stmtexpr_remover(systemtap_session
& s
, bool& r
):
2754 session(s
), relaxed_p(r
) {}
2756 void visit_block (block
*s
);
2757 void visit_try_block (try_block
*s
);
2758 void visit_null_statement (null_statement
*s
);
2759 void visit_if_statement (if_statement
* s
);
2760 void visit_foreach_loop (foreach_loop
*s
);
2761 void visit_for_loop (for_loop
*s
);
2762 // XXX: and other places where stmt_expr's might be nested
2764 void visit_expr_statement (expr_statement
*s
);
2769 dead_stmtexpr_remover::visit_null_statement (null_statement
*s
)
2772 if (session
.verbose
>2)
2773 clog
<< _("Eliding side-effect-free null statement ") << *s
->tok
<< endl
;
2780 dead_stmtexpr_remover::visit_block (block
*s
)
2782 vector
<statement
*> new_stmts
;
2783 for (unsigned i
=0; i
<s
->statements
.size(); i
++ )
2785 statement
* new_stmt
= require (s
->statements
[i
], true);
2788 // flatten nested blocks into this one
2789 block
*b
= dynamic_cast<block
*>(new_stmt
);
2792 if (session
.verbose
>2)
2793 clog
<< _("Flattening nested block ") << *b
->tok
<< endl
;
2794 new_stmts
.insert(new_stmts
.end(),
2795 b
->statements
.begin(), b
->statements
.end());
2799 new_stmts
.push_back (new_stmt
);
2802 if (new_stmts
.size() == 0)
2804 if (session
.verbose
>2)
2805 clog
<< _("Eliding side-effect-free empty block ") << *s
->tok
<< endl
;
2808 else if (new_stmts
.size() == 1)
2810 if (session
.verbose
>2)
2811 clog
<< _("Eliding side-effect-free singleton block ") << *s
->tok
<< endl
;
2812 provide (new_stmts
[0]);
2816 s
->statements
= new_stmts
;
2822 dead_stmtexpr_remover::visit_try_block (try_block
*s
)
2824 replace (s
->try_block
, true);
2825 replace (s
->catch_block
, true); // null catch{} is ok and useful
2826 if (s
->try_block
== 0)
2828 if (session
.verbose
>2)
2829 clog
<< _("Eliding empty try {} block ") << *s
->tok
<< endl
;
2837 dead_stmtexpr_remover::visit_if_statement (if_statement
*s
)
2839 replace (s
->thenblock
, true);
2840 replace (s
->elseblock
, true);
2842 if (s
->thenblock
== 0)
2844 if (s
->elseblock
== 0)
2846 // We may be able to elide this statement, if the condition
2847 // expression is side-effect-free.
2848 varuse_collecting_visitor
vct(session
);
2849 s
->condition
->visit(& vct
);
2850 if (vct
.side_effect_free ())
2852 if (session
.verbose
>2)
2853 clog
<< _("Eliding side-effect-free if statement ")
2855 s
= 0; // yeah, baby
2859 // We can still turn it into a simple expr_statement though...
2860 if (session
.verbose
>2)
2861 clog
<< _("Creating simple evaluation from if statement ")
2863 expr_statement
*es
= new expr_statement
;
2864 es
->value
= s
->condition
;
2865 es
->tok
= es
->value
->tok
;
2872 // For an else without a then, we can invert the condition logic to
2873 // avoid having a null statement in the thenblock
2874 if (session
.verbose
>2)
2875 clog
<< _("Inverting the condition of if statement ")
2877 unary_expression
*ue
= new unary_expression
;
2878 ue
->operand
= s
->condition
;
2879 ue
->tok
= ue
->operand
->tok
;
2882 s
->thenblock
= s
->elseblock
;
2890 dead_stmtexpr_remover::visit_foreach_loop (foreach_loop
*s
)
2892 replace (s
->block
, true);
2896 // XXX what if s->limit has side effects?
2897 // XXX what about s->indexes or s->value used outside the loop?
2898 if(session
.verbose
> 2)
2899 clog
<< _("Eliding side-effect-free foreach statement ") << *s
->tok
<< endl
;
2900 s
= 0; // yeah, baby
2906 dead_stmtexpr_remover::visit_for_loop (for_loop
*s
)
2908 replace (s
->block
, true);
2912 // We may be able to elide this statement, if the condition
2913 // expression is side-effect-free.
2914 varuse_collecting_visitor
vct(session
);
2915 if (s
->init
) s
->init
->visit(& vct
);
2916 s
->cond
->visit(& vct
);
2917 if (s
->incr
) s
->incr
->visit(& vct
);
2918 if (vct
.side_effect_free ())
2920 if (session
.verbose
>2)
2921 clog
<< _("Eliding side-effect-free for statement ") << *s
->tok
<< endl
;
2922 s
= 0; // yeah, baby
2926 // Can't elide this whole statement; put a null in there.
2927 s
->block
= new null_statement(s
->tok
);
2936 dead_stmtexpr_remover::visit_expr_statement (expr_statement
*s
)
2938 // Run a varuse query against the operand expression. If it has no
2939 // side-effects, replace the entire statement expression by a null
2940 // statement with the provide() call.
2942 // Unlike many other visitors, we do *not* traverse this outermost
2943 // one into the expression subtrees. There is no need - no
2944 // expr_statement nodes will be found there. (Function bodies
2945 // need to be visited explicitly by our caller.)
2947 // NB. While we don't share nodes in the parse tree, let's not
2948 // deallocate *s anyway, just in case...
2950 varuse_collecting_visitor
vut(session
);
2951 s
->value
->visit (& vut
);
2953 if (vut
.side_effect_free_wrt (focal_vars
))
2955 /* PR 1119: NB: this message is not a good idea here. It can
2956 name some arbitrary RHS expression of an assignment.
2957 if (s->value->tok->location.file->name == session.user_file->name) // not tapset
2958 session.print_warning("eliding never-assigned ", *s->value->tok);
2961 if (session
.is_user_file(s
->value
->tok
->location
.file
->name
))
2962 session
.print_warning("Eliding side-effect-free expression ", s
->tok
);
2964 // NB: this 0 pointer is invalid to leave around for any length of
2965 // time, but the parent parse tree objects above handle it.
2973 void semantic_pass_opt4 (systemtap_session
& s
, bool& relaxed_p
)
2975 // Finally, let's remove some statement-expressions that have no
2976 // side-effect. These should be exactly those whose private varuse
2977 // visitors come back with an empty "written" and "embedded" lists.
2979 dead_stmtexpr_remover
duv (s
, relaxed_p
);
2980 // This instance may be reused for multiple probe/function body trims.
2982 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
2984 assert_no_interrupts();
2986 derived_probe
* p
= s
.probes
[i
];
2988 duv
.focal_vars
.clear ();
2989 duv
.focal_vars
.insert (s
.globals
.begin(),
2991 duv
.focal_vars
.insert (p
->locals
.begin(),
2994 duv
.replace (p
->body
, true);
2997 if (! s
.timing
) // PR10070
2998 s
.print_warning (_F("side-effect-free probe '%s'", p
->name
.c_str()), p
->tok
);
3000 p
->body
= new null_statement(p
->tok
);
3002 // XXX: possible duplicate warnings; see below
3005 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
3007 assert_no_interrupts();
3009 functiondecl
* fn
= it
->second
;
3010 duv
.focal_vars
.clear ();
3011 duv
.focal_vars
.insert (fn
->locals
.begin(),
3013 duv
.focal_vars
.insert (fn
->formal_args
.begin(),
3014 fn
->formal_args
.end());
3015 duv
.focal_vars
.insert (s
.globals
.begin(),
3018 duv
.replace (fn
->body
, true);
3021 s
.print_warning (_F("side-effect-free function '%s'", fn
->name
.c_str()), fn
->tok
);
3023 fn
->body
= new null_statement(fn
->tok
);
3025 // XXX: the next iteration of the outer optimization loop may
3026 // take this new null_statement away again, and thus give us a
3027 // fresh warning. It would be better if this fixup was performed
3028 // only after the relaxation iterations.
3029 // XXX: or else see bug #6469.
3035 // ------------------------------------------------------------------------
3037 // The goal of this visitor is to reduce top-level expressions in void context
3038 // into separate statements that evaluate each subcomponent of the expression.
3039 // The dead-statement-remover can later remove some parts if they have no side
3042 // All expressions must be overridden here so we never visit their subexpressions
3043 // accidentally. Thus, the only visited expressions should be value of an
3046 // For an expression to replace its expr_statement with something else, it will
3047 // let the new statement provide(), and then provide(0) for itself. The
3048 // expr_statement will take this as a sign that it's been replaced.
3049 struct void_statement_reducer
: public update_visitor
3051 systemtap_session
& session
;
3053 set
<vardecl
*> focal_vars
; // vars considered subject to side-effects
3055 void_statement_reducer(systemtap_session
& s
, bool& r
):
3056 session(s
), relaxed_p(r
) {}
3058 void visit_expr_statement (expr_statement
* s
);
3060 // expressions in conditional / loop controls are definitely a side effect,
3061 // but still recurse into the child statements
3062 void visit_if_statement (if_statement
* s
);
3063 void visit_for_loop (for_loop
* s
);
3064 void visit_foreach_loop (foreach_loop
* s
);
3066 // these expressions get rewritten into their statement equivalents
3067 void visit_logical_or_expr (logical_or_expr
* e
);
3068 void visit_logical_and_expr (logical_and_expr
* e
);
3069 void visit_ternary_expression (ternary_expression
* e
);
3071 // all of these can (usually) be reduced into simpler statements
3072 void visit_binary_expression (binary_expression
* e
);
3073 void visit_unary_expression (unary_expression
* e
);
3074 void visit_regex_query (regex_query
* e
); // XXX depends on subexpr extraction
3075 void visit_comparison (comparison
* e
);
3076 void visit_concatenation (concatenation
* e
);
3077 void visit_functioncall (functioncall
* e
);
3078 void visit_print_format (print_format
* e
);
3079 void visit_target_symbol (target_symbol
* e
);
3080 void visit_atvar_op (atvar_op
* e
);
3081 void visit_cast_op (cast_op
* e
);
3082 void visit_autocast_op (autocast_op
* e
);
3083 void visit_defined_op (defined_op
* e
);
3085 // these are a bit hairy to grok due to the intricacies of indexables and
3086 // stats, so I'm chickening out and skipping them...
3087 void visit_array_in (array_in
* e
) { provide (e
); }
3088 void visit_arrayindex (arrayindex
* e
) { provide (e
); }
3089 void visit_stat_op (stat_op
* e
) { provide (e
); }
3090 void visit_hist_op (hist_op
* e
) { provide (e
); }
3092 // these can't be reduced because they always have an effect
3093 void visit_return_statement (return_statement
* s
) { provide (s
); }
3094 void visit_delete_statement (delete_statement
* s
) { provide (s
); }
3095 void visit_pre_crement (pre_crement
* e
) { provide (e
); }
3096 void visit_post_crement (post_crement
* e
) { provide (e
); }
3097 void visit_assignment (assignment
* e
) { provide (e
); }
3100 void reduce_target_symbol (target_symbol
* e
, expression
* operand
=NULL
);
3105 void_statement_reducer::visit_expr_statement (expr_statement
* s
)
3107 replace (s
->value
, true);
3109 // if the expression provides 0, that's our signal that a new
3110 // statement has been provided, so we shouldn't provide this one.
3116 void_statement_reducer::visit_if_statement (if_statement
* s
)
3118 // s->condition is never void
3119 replace (s
->thenblock
);
3120 replace (s
->elseblock
);
3125 void_statement_reducer::visit_for_loop (for_loop
* s
)
3127 // s->init/cond/incr are never void
3133 void_statement_reducer::visit_foreach_loop (foreach_loop
* s
)
3135 // s->indexes/base/value/limit are never void
3141 void_statement_reducer::visit_logical_or_expr (logical_or_expr
* e
)
3143 // In void context, the evaluation of "a || b" is exactly like
3144 // "if (!a) b", so let's do that instead.
3146 if (session
.verbose
>2)
3147 clog
<< _("Creating if statement from unused logical-or ")
3150 if_statement
*is
= new if_statement
;
3154 unary_expression
*ue
= new unary_expression
;
3155 ue
->operand
= e
->left
;
3160 expr_statement
*es
= new expr_statement
;
3161 es
->value
= e
->right
;
3162 es
->tok
= es
->value
->tok
;
3172 void_statement_reducer::visit_logical_and_expr (logical_and_expr
* e
)
3174 // In void context, the evaluation of "a && b" is exactly like
3175 // "if (a) b", so let's do that instead.
3177 if (session
.verbose
>2)
3178 clog
<< _("Creating if statement from unused logical-and ")
3181 if_statement
*is
= new if_statement
;
3184 is
->condition
= e
->left
;
3186 expr_statement
*es
= new expr_statement
;
3187 es
->value
= e
->right
;
3188 es
->tok
= es
->value
->tok
;
3198 void_statement_reducer::visit_ternary_expression (ternary_expression
* e
)
3200 // In void context, the evaluation of "a ? b : c" is exactly like
3201 // "if (a) b else c", so let's do that instead.
3203 if (session
.verbose
>2)
3204 clog
<< _("Creating if statement from unused ternary expression ")
3207 if_statement
*is
= new if_statement
;
3209 is
->condition
= e
->cond
;
3211 expr_statement
*es
= new expr_statement
;
3212 es
->value
= e
->truevalue
;
3213 es
->tok
= es
->value
->tok
;
3216 es
= new expr_statement
;
3217 es
->value
= e
->falsevalue
;
3218 es
->tok
= es
->value
->tok
;
3228 void_statement_reducer::visit_binary_expression (binary_expression
* e
)
3230 // When the result of a binary operation isn't needed, it's just as good to
3231 // evaluate the operands as sequential statements in a block.
3233 if (session
.verbose
>2)
3234 clog
<< _("Eliding unused binary ") << *e
->tok
<< endl
;
3236 block
*b
= new block
;
3239 expr_statement
*es
= new expr_statement
;
3240 es
->value
= e
->left
;
3241 es
->tok
= es
->value
->tok
;
3242 b
->statements
.push_back(es
);
3244 es
= new expr_statement
;
3245 es
->value
= e
->right
;
3246 es
->tok
= es
->value
->tok
;
3247 b
->statements
.push_back(es
);
3256 void_statement_reducer::visit_unary_expression (unary_expression
* e
)
3258 // When the result of a unary operation isn't needed, it's just as good to
3259 // evaluate the operand directly
3261 if (session
.verbose
>2)
3262 clog
<< _("Eliding unused unary ") << *e
->tok
<< endl
;
3265 e
->operand
->visit(this);
3269 void_statement_reducer::visit_regex_query (regex_query
* e
)
3271 // TODOXXX After subexpression extraction is implemented,
3272 // regular expression matches *may* have side-effects in
3273 // terms of producing matched subexpressions, e.g.:
3275 // str =~ "pat"; println(matched(0));
3277 // It's debatable if we want to actually allow this, though.
3279 // Treat e as a unary expression on the left operand -- since the
3280 // right hand side must be a literal (as verified by the parser),
3281 // evaluating it never has side effects.
3283 if (session
.verbose
>2)
3284 clog
<< _("Eliding regex query ") << *e
->tok
<< endl
;
3287 e
->left
->visit(this);
3291 void_statement_reducer::visit_comparison (comparison
* e
)
3293 visit_binary_expression(e
);
3297 void_statement_reducer::visit_concatenation (concatenation
* e
)
3299 visit_binary_expression(e
);
3303 void_statement_reducer::visit_functioncall (functioncall
* e
)
3305 // If a function call is pure and its result ignored, we can elide the call
3306 // and just evaluate the arguments in sequence
3308 if (!e
->args
.size())
3314 varuse_collecting_visitor
vut(session
);
3315 vut
.seen
.insert (e
->referent
);
3316 vut
.current_function
= e
->referent
;
3317 e
->referent
->body
->visit (& vut
);
3318 if (!vut
.side_effect_free_wrt (focal_vars
))
3324 if (session
.verbose
>2)
3325 clog
<< _("Eliding side-effect-free function call ") << *e
->tok
<< endl
;
3327 block
*b
= new block
;
3330 for (unsigned i
=0; i
<e
->args
.size(); i
++ )
3332 expr_statement
*es
= new expr_statement
;
3333 es
->value
= e
->args
[i
];
3334 es
->tok
= es
->value
->tok
;
3335 b
->statements
.push_back(es
);
3345 void_statement_reducer::visit_print_format (print_format
* e
)
3347 // When an sprint's return value is ignored, we can simply evaluate the
3348 // arguments in sequence
3350 if (e
->print_to_stream
|| !e
->args
.size())
3356 if (session
.verbose
>2)
3357 clog
<< _("Eliding unused print ") << *e
->tok
<< endl
;
3359 block
*b
= new block
;
3362 for (unsigned i
=0; i
<e
->args
.size(); i
++ )
3364 expr_statement
*es
= new expr_statement
;
3365 es
->value
= e
->args
[i
];
3366 es
->tok
= es
->value
->tok
;
3367 b
->statements
.push_back(es
);
3377 void_statement_reducer::reduce_target_symbol (target_symbol
* e
,
3378 expression
* operand
)
3380 // When the result of any target_symbol isn't needed, it's just as good to
3381 // evaluate the operand and any array indexes directly
3383 block
*b
= new block
;
3388 expr_statement
*es
= new expr_statement
;
3389 es
->value
= operand
;
3390 es
->tok
= es
->value
->tok
;
3391 b
->statements
.push_back(es
);
3394 for (unsigned i
=0; i
<e
->components
.size(); i
++ )
3396 if (e
->components
[i
].type
!= target_symbol::comp_expression_array_index
)
3399 expr_statement
*es
= new expr_statement
;
3400 es
->value
= e
->components
[i
].expr_index
;
3401 es
->tok
= es
->value
->tok
;
3402 b
->statements
.push_back(es
);
3412 void_statement_reducer::visit_atvar_op (atvar_op
* e
)
3414 if (session
.verbose
>2)
3415 clog
<< _("Eliding unused target symbol ") << *e
->tok
<< endl
;
3416 reduce_target_symbol (e
);
3420 void_statement_reducer::visit_target_symbol (target_symbol
* e
)
3422 if (session
.verbose
>2)
3423 clog
<< _("Eliding unused target symbol ") << *e
->tok
<< endl
;
3424 reduce_target_symbol (e
);
3428 void_statement_reducer::visit_cast_op (cast_op
* e
)
3430 if (session
.verbose
>2)
3431 clog
<< _("Eliding unused typecast ") << *e
->tok
<< endl
;
3432 reduce_target_symbol (e
, e
->operand
);
3436 void_statement_reducer::visit_autocast_op (autocast_op
* e
)
3438 if (session
.verbose
>2)
3439 clog
<< _("Eliding unused autocast ") << *e
->tok
<< endl
;
3440 reduce_target_symbol (e
, e
->operand
);
3445 void_statement_reducer::visit_defined_op (defined_op
* e
)
3447 // When the result of a @defined operation isn't needed, just elide
3448 // it entirely. Its operand $expression must already be
3449 // side-effect-free.
3451 if (session
.verbose
>2)
3452 clog
<< _("Eliding unused check ") << *e
->tok
<< endl
;
3461 void semantic_pass_opt5 (systemtap_session
& s
, bool& relaxed_p
)
3463 // Let's simplify statements with unused computed values.
3465 void_statement_reducer
vuv (s
, relaxed_p
);
3466 // This instance may be reused for multiple probe/function body trims.
3468 vuv
.focal_vars
.insert (s
.globals
.begin(), s
.globals
.end());
3470 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
3471 vuv
.replace (s
.probes
[i
]->body
);
3472 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
3473 it
!= s
.functions
.end(); it
++)
3474 vuv
.replace (it
->second
->body
);
3478 struct const_folder
: public update_visitor
3480 systemtap_session
& session
;
3483 const_folder(systemtap_session
& s
, bool& r
):
3484 session(s
), relaxed_p(r
), last_number(0), last_string(0) {}
3486 literal_number
* last_number
;
3487 literal_number
* get_number(expression
*& e
);
3488 void visit_literal_number (literal_number
* e
);
3490 literal_string
* last_string
;
3491 literal_string
* get_string(expression
*& e
);
3492 void visit_literal_string (literal_string
* e
);
3494 void get_literal(expression
*& e
, literal_number
*& n
, literal_string
*& s
);
3496 void visit_if_statement (if_statement
* s
);
3497 void visit_for_loop (for_loop
* s
);
3498 void visit_foreach_loop (foreach_loop
* s
);
3499 void visit_binary_expression (binary_expression
* e
);
3500 void visit_unary_expression (unary_expression
* e
);
3501 void visit_logical_or_expr (logical_or_expr
* e
);
3502 void visit_logical_and_expr (logical_and_expr
* e
);
3503 // void visit_regex_query (regex_query* e); // XXX: would require executing dfa at compile-time
3504 void visit_comparison (comparison
* e
);
3505 void visit_concatenation (concatenation
* e
);
3506 void visit_ternary_expression (ternary_expression
* e
);
3507 void visit_defined_op (defined_op
* e
);
3508 void visit_target_symbol (target_symbol
* e
);
3512 const_folder::get_literal(expression
*& e
,
3517 n
= (e
== last_number
) ? last_number
: NULL
;
3518 s
= (e
== last_string
) ? last_string
: NULL
;
3522 const_folder::get_number(expression
*& e
)
3525 return (e
== last_number
) ? last_number
: NULL
;
3529 const_folder::visit_literal_number (literal_number
* e
)
3536 const_folder::get_string(expression
*& e
)
3539 return (e
== last_string
) ? last_string
: NULL
;
3543 const_folder::visit_literal_string (literal_string
* e
)
3550 const_folder::visit_if_statement (if_statement
* s
)
3552 literal_number
* cond
= get_number (s
->condition
);
3555 replace (s
->thenblock
);
3556 replace (s
->elseblock
);
3561 if (session
.verbose
>2)
3562 clog
<< _F("Collapsing constant-%" PRIi64
" if-statement %s",
3563 cond
->value
, lex_cast(*s
->tok
).c_str()) << endl
;
3566 statement
* n
= cond
->value
? s
->thenblock
: s
->elseblock
;
3570 provide (new null_statement (s
->tok
));
3575 const_folder::visit_for_loop (for_loop
* s
)
3577 literal_number
* cond
= get_number (s
->cond
);
3578 if (!cond
|| cond
->value
)
3587 if (session
.verbose
>2)
3588 clog
<< _("Collapsing constantly-false for-loop ") << *s
->tok
<< endl
;
3592 s
->init
->visit (this);
3594 provide (new null_statement (s
->tok
));
3599 const_folder::visit_foreach_loop (foreach_loop
* s
)
3601 literal_number
* limit
= get_number (s
->limit
);
3602 if (!limit
|| limit
->value
> 0)
3604 for (unsigned i
= 0; i
< s
->indexes
.size(); ++i
)
3605 replace (s
->indexes
[i
]);
3613 if (session
.verbose
>2)
3614 clog
<< _("Collapsing constantly-limited foreach-loop ") << *s
->tok
<< endl
;
3617 provide (new null_statement (s
->tok
));
3622 const_folder::visit_binary_expression (binary_expression
* e
)
3625 literal_number
* left
= get_number (e
->left
);
3626 literal_number
* right
= get_number (e
->right
);
3628 if (right
&& !right
->value
&& (e
->op
== "/" || e
->op
== "%"))
3630 // Give divide-by-zero a chance to be optimized out elsewhere,
3631 // and if not it will be a runtime error anyway...
3639 value
= left
->value
+ right
->value
;
3640 else if (e
->op
== "-")
3641 value
= left
->value
- right
->value
;
3642 else if (e
->op
== "*")
3643 value
= left
->value
* right
->value
;
3644 else if (e
->op
== "&")
3645 value
= left
->value
& right
->value
;
3646 else if (e
->op
== "|")
3647 value
= left
->value
| right
->value
;
3648 else if (e
->op
== "^")
3649 value
= left
->value
^ right
->value
;
3650 else if (e
->op
== ">>")
3651 value
= left
->value
>> max(min(right
->value
, (int64_t)64), (int64_t)0);
3652 else if (e
->op
== "<<")
3653 value
= left
->value
<< max(min(right
->value
, (int64_t)64), (int64_t)0);
3654 else if (e
->op
== "/")
3655 value
= (left
->value
== LLONG_MIN
&& right
->value
== -1) ? LLONG_MIN
:
3656 left
->value
/ right
->value
;
3657 else if (e
->op
== "%")
3658 value
= (left
->value
== LLONG_MIN
&& right
->value
== -1) ? 0 :
3659 left
->value
% right
->value
;
3661 throw SEMANTIC_ERROR (_("unsupported binary operator ") + e
->op
);
3664 else if ((left
&& ((left
->value
== 0 && (e
->op
== "*" || e
->op
== "&" ||
3665 e
->op
== ">>" || e
->op
== "<<" )) ||
3666 (left
->value
==-1 && (e
->op
== "|" || e
->op
== ">>"))))
3668 (right
&& ((right
->value
== 0 && (e
->op
== "*" || e
->op
== "&")) ||
3669 (right
->value
== 1 && (e
->op
== "%")) ||
3670 (right
->value
==-1 && (e
->op
== "%" || e
->op
== "|")))))
3672 expression
* other
= left
? e
->right
: e
->left
;
3673 varuse_collecting_visitor
vu(session
);
3675 if (!vu
.side_effect_free())
3682 value
= left
->value
;
3683 else if (e
->op
== "%")
3686 value
= right
->value
;
3689 else if ((left
&& ((left
->value
== 0 && (e
->op
== "+" || e
->op
== "|" ||
3691 (left
->value
== 1 && (e
->op
== "*")) ||
3692 (left
->value
==-1 && (e
->op
== "&"))))
3694 (right
&& ((right
->value
== 0 && (e
->op
== "+" || e
->op
== "-" ||
3695 e
->op
== "|" || e
->op
== "^")) ||
3696 (right
->value
== 1 && (e
->op
== "*" || e
->op
== "/")) ||
3697 (right
->value
==-1 && (e
->op
== "&")) ||
3698 (right
->value
<= 0 && (e
->op
== ">>" || e
->op
== "<<")))))
3700 if (session
.verbose
>2)
3701 clog
<< _("Collapsing constant-identity binary operator ") << *e
->tok
<< endl
;
3704 provide (left
? e
->right
: e
->left
);
3714 if (session
.verbose
>2)
3715 clog
<< _F("Collapsing constant-%" PRIi64
" binary operator %s",
3716 value
, lex_cast(*e
->tok
).c_str()) << endl
;
3719 literal_number
* n
= new literal_number(value
);
3725 const_folder::visit_unary_expression (unary_expression
* e
)
3727 literal_number
* operand
= get_number (e
->operand
);
3732 if (session
.verbose
>2)
3733 clog
<< _("Collapsing constant unary ") << *e
->tok
<< endl
;
3736 literal_number
* n
= new literal_number (*operand
);
3740 else if (e
->op
== "-")
3741 n
->value
= -n
->value
;
3742 else if (e
->op
== "!")
3743 n
->value
= !n
->value
;
3744 else if (e
->op
== "~")
3745 n
->value
= ~n
->value
;
3747 throw SEMANTIC_ERROR (_("unsupported unary operator ") + e
->op
);
3753 const_folder::visit_logical_or_expr (logical_or_expr
* e
)
3756 literal_number
* left
= get_number (e
->left
);
3757 literal_number
* right
= get_number (e
->right
);
3760 value
= left
->value
|| right
->value
;
3762 else if ((left
&& left
->value
) || (right
&& right
->value
))
3764 // If the const is on the left, we get to short-circuit the right
3765 // immediately. Otherwise, we can only eliminate the LHS if it's pure.
3768 varuse_collecting_visitor
vu(session
);
3769 e
->left
->visit(&vu
);
3770 if (!vu
.side_effect_free())
3780 // We might also get rid of useless "0||x" and "x||0", except it does
3781 // normalize x to 0 or 1. We could change it to "!!x", but it's not clear
3782 // that this would gain us much.
3790 if (session
.verbose
>2)
3791 clog
<< _("Collapsing constant logical-OR ") << *e
->tok
<< endl
;
3794 literal_number
* n
= new literal_number(value
);
3800 const_folder::visit_logical_and_expr (logical_and_expr
* e
)
3803 literal_number
* left
= get_number (e
->left
);
3804 literal_number
* right
= get_number (e
->right
);
3807 value
= left
->value
&& right
->value
;
3809 else if ((left
&& !left
->value
) || (right
&& !right
->value
))
3811 // If the const is on the left, we get to short-circuit the right
3812 // immediately. Otherwise, we can only eliminate the LHS if it's pure.
3815 varuse_collecting_visitor
vu(session
);
3816 e
->left
->visit(&vu
);
3817 if (!vu
.side_effect_free())
3827 // We might also get rid of useless "1&&x" and "x&&1", except it does
3828 // normalize x to 0 or 1. We could change it to "!!x", but it's not clear
3829 // that this would gain us much.
3837 if (session
.verbose
>2)
3838 clog
<< _("Collapsing constant logical-AND ") << *e
->tok
<< endl
;
3841 literal_number
* n
= new literal_number(value
);
3847 const_folder::visit_comparison (comparison
* e
)
3851 literal_number
*left_num
, *right_num
;
3852 literal_string
*left_str
, *right_str
;
3853 get_literal(e
->left
, left_num
, left_str
);
3854 get_literal(e
->right
, right_num
, right_str
);
3856 if (left_str
&& right_str
)
3857 comp
= left_str
->value
.compare(right_str
->value
);
3859 else if (left_num
&& right_num
)
3860 comp
= left_num
->value
< right_num
->value
? -1 :
3861 left_num
->value
> right_num
->value
? 1 : 0;
3863 else if ((left_num
&& ((left_num
->value
== LLONG_MIN
&&
3864 (e
->op
== "<=" || e
->op
== ">")) ||
3865 (left_num
->value
== LLONG_MAX
&&
3866 (e
->op
== ">=" || e
->op
== "<"))))
3868 (right_num
&& ((right_num
->value
== LLONG_MIN
&&
3869 (e
->op
== ">=" || e
->op
== "<")) ||
3870 (right_num
->value
== LLONG_MAX
&&
3871 (e
->op
== "<=" || e
->op
== ">")))))
3873 expression
* other
= left_num
? e
->right
: e
->left
;
3874 varuse_collecting_visitor
vu(session
);
3876 if (!vu
.side_effect_free())
3880 if (session
.verbose
>2)
3881 clog
<< _("Collapsing constant-boundary comparison ") << *e
->tok
<< endl
;
3884 // ops <= and >= are true, < and > are false
3885 literal_number
* n
= new literal_number( e
->op
.length() == 2 );
3898 if (session
.verbose
>2)
3899 clog
<< _("Collapsing constant comparison ") << *e
->tok
<< endl
;
3905 else if (e
->op
== "!=")
3907 else if (e
->op
== "<")
3909 else if (e
->op
== ">")
3911 else if (e
->op
== "<=")
3913 else if (e
->op
== ">=")
3916 throw SEMANTIC_ERROR (_("unsupported comparison operator ") + e
->op
);
3918 literal_number
* n
= new literal_number(value
);
3924 const_folder::visit_concatenation (concatenation
* e
)
3926 literal_string
* left
= get_string (e
->left
);
3927 literal_string
* right
= get_string (e
->right
);
3931 if (session
.verbose
>2)
3932 clog
<< _("Collapsing constant concatenation ") << *e
->tok
<< endl
;
3935 literal_string
* n
= new literal_string (*left
);
3937 n
->value
.append(right
->value
);
3940 else if ((left
&& left
->value
.empty()) ||
3941 (right
&& right
->value
.empty()))
3943 if (session
.verbose
>2)
3944 clog
<< _("Collapsing identity concatenation ") << *e
->tok
<< endl
;
3946 provide(left
? e
->right
: e
->left
);
3953 const_folder::visit_ternary_expression (ternary_expression
* e
)
3955 literal_number
* cond
= get_number (e
->cond
);
3958 replace (e
->truevalue
);
3959 replace (e
->falsevalue
);
3964 if (session
.verbose
>2)
3965 clog
<< _F("Collapsing constant-%" PRIi64
" ternary %s",
3966 cond
->value
, lex_cast(*e
->tok
).c_str()) << endl
;
3969 expression
* n
= cond
->value
? e
->truevalue
: e
->falsevalue
;
3975 const_folder::visit_defined_op (defined_op
* e
)
3977 // If a @defined makes it this far, then it is, de facto, undefined.
3979 if (session
.verbose
>2)
3980 clog
<< _("Collapsing untouched @defined check ") << *e
->tok
<< endl
;
3983 literal_number
* n
= new literal_number (0);
3989 const_folder::visit_target_symbol (target_symbol
* e
)
3991 if (session
.skip_badvars
)
3993 // Upon user request for ignoring context, the symbol is replaced
3994 // with a literal 0 and a warning message displayed
3995 // XXX this ignores possible side-effects, e.g. in array indexes
3996 literal_number
* ln_zero
= new literal_number (0);
3997 ln_zero
->tok
= e
->tok
;
3999 session
.print_warning (_("Bad $context variable being substituted with literal 0"),
4004 update_visitor::visit_target_symbol (e
);
4007 static void semantic_pass_const_fold (systemtap_session
& s
, bool& relaxed_p
)
4009 // Let's simplify statements with constant values.
4011 const_folder
cf (s
, relaxed_p
);
4012 // This instance may be reused for multiple probe/function body trims.
4014 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
4015 cf
.replace (s
.probes
[i
]->body
);
4016 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
4017 it
!= s
.functions
.end(); it
++)
4018 cf
.replace (it
->second
->body
);
4022 struct dead_control_remover
: public traversing_visitor
4024 systemtap_session
& session
;
4028 dead_control_remover(systemtap_session
& s
, bool& r
):
4029 session(s
), relaxed_p(r
), control(NULL
) {}
4031 void visit_block (block
*b
);
4033 // When a block contains any of these, the following statements are dead.
4034 void visit_return_statement (return_statement
* s
) { control
= s
; }
4035 void visit_next_statement (next_statement
* s
) { control
= s
; }
4036 void visit_break_statement (break_statement
* s
) { control
= s
; }
4037 void visit_continue_statement (continue_statement
* s
) { control
= s
; }
4041 void dead_control_remover::visit_block (block
* b
)
4043 vector
<statement
*>& vs
= b
->statements
;
4044 if (vs
.size() == 0) /* else (size_t) size()-1 => very big */
4046 for (size_t i
= 0; i
< vs
.size() - 1; ++i
)
4048 vs
[i
]->visit (this);
4049 if (vs
[i
] == control
)
4051 session
.print_warning(_("statement will never be reached"),
4053 vs
.erase(vs
.begin() + i
+ 1, vs
.end());
4061 static void semantic_pass_dead_control (systemtap_session
& s
, bool& relaxed_p
)
4063 // Let's remove code that follow unconditional control statements
4065 dead_control_remover
dc (s
, relaxed_p
);
4067 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
4068 s
.probes
[i
]->body
->visit(&dc
);
4070 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
4071 it
!= s
.functions
.end(); it
++)
4072 it
->second
->body
->visit(&dc
);
4076 struct duplicate_function_remover
: public functioncall_traversing_visitor
4078 systemtap_session
& s
;
4079 map
<functiondecl
*, functiondecl
*>& duplicate_function_map
;
4081 duplicate_function_remover(systemtap_session
& sess
,
4082 map
<functiondecl
*, functiondecl
*>&dfm
):
4083 s(sess
), duplicate_function_map(dfm
) {};
4085 void visit_functioncall (functioncall
* e
);
4089 duplicate_function_remover::visit_functioncall (functioncall
*e
)
4091 functioncall_traversing_visitor::visit_functioncall (e
);
4093 // If the current function call reference points to a function that
4094 // is a duplicate, replace it.
4095 if (duplicate_function_map
.count(e
->referent
) != 0)
4098 clog
<< _F("Changing %s reference to %s reference\n",
4099 e
->referent
->name
.c_str(), duplicate_function_map
[e
->referent
]->name
.c_str());
4100 e
->tok
= duplicate_function_map
[e
->referent
]->tok
;
4101 e
->function
= duplicate_function_map
[e
->referent
]->name
;
4102 e
->referent
= duplicate_function_map
[e
->referent
];
4107 get_functionsig (functiondecl
* f
)
4111 // Get the "name:args body" of the function in s. We have to
4112 // include the args since the function 'x1(a, b)' is different than
4113 // the function 'x2(b, a)' even if the bodies of the two functions
4114 // are exactly the same.
4118 // printsig puts f->name + ':' on the front. Remove this
4119 // (otherwise, functions would never compare equal).
4120 string str
= s
.str().erase(0, f
->name
.size() + 1);
4122 // Return the function signature.
4126 void semantic_pass_opt6 (systemtap_session
& s
, bool& relaxed_p
)
4128 // Walk through all the functions, looking for duplicates.
4129 map
<string
, functiondecl
*> functionsig_map
;
4130 map
<functiondecl
*, functiondecl
*> duplicate_function_map
;
4133 vector
<functiondecl
*> newly_zapped_functions
;
4134 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
4136 functiondecl
*fd
= it
->second
;
4137 string functionsig
= get_functionsig(fd
);
4139 if (functionsig_map
.count(functionsig
) == 0)
4141 // This function is unique. Remember it.
4142 functionsig_map
[functionsig
] = fd
;
4146 // This function is a duplicate.
4147 duplicate_function_map
[fd
] = functionsig_map
[functionsig
];
4148 newly_zapped_functions
.push_back (fd
);
4152 for (unsigned i
=0; i
<newly_zapped_functions
.size(); i
++)
4154 map
<string
,functiondecl
*>::iterator where
= s
.functions
.find (newly_zapped_functions
[i
]->name
);
4155 assert (where
!= s
.functions
.end());
4156 s
.functions
.erase (where
);
4160 // If we have duplicate functions, traverse down the tree, replacing
4161 // the appropriate function calls.
4162 // duplicate_function_remover::visit_functioncall() handles the
4163 // details of replacing the function calls.
4164 if (duplicate_function_map
.size() != 0)
4166 duplicate_function_remover
dfr (s
, duplicate_function_map
);
4168 for (unsigned i
=0; i
< s
.probes
.size(); i
++)
4169 s
.probes
[i
]->body
->visit(&dfr
);
4175 semantic_pass_optimize1 (systemtap_session
& s
)
4177 // In this pass, we attempt to rewrite probe/function bodies to
4178 // eliminate some blatantly unnecessary code. This is run before
4179 // type inference, but after symbol resolution and derived_probe
4180 // creation. We run an outer "relaxation" loop that repeats the
4181 // optimizations until none of them find anything to remove.
4185 // Save the old value of suppress_warnings, as we will be changing
4187 save_and_restore
<bool> suppress_warnings(& s
.suppress_warnings
);
4189 bool relaxed_p
= false;
4190 unsigned iterations
= 0;
4193 assert_no_interrupts();
4195 relaxed_p
= true; // until proven otherwise
4197 // If the verbosity is high enough, always print warnings (overrides -w),
4198 // or if not, always suppress warnings for every itteration after the first.
4200 s
.suppress_warnings
= false;
4201 else if (iterations
> 0)
4202 s
.suppress_warnings
= true;
4206 semantic_pass_opt1 (s
, relaxed_p
);
4207 semantic_pass_opt2 (s
, relaxed_p
, iterations
); // produce some warnings only on iteration=0
4208 semantic_pass_opt3 (s
, relaxed_p
);
4209 semantic_pass_opt4 (s
, relaxed_p
);
4210 semantic_pass_opt5 (s
, relaxed_p
);
4213 // For listing mode, we need const-folding regardless of optimization so
4214 // that @defined expressions can be properly resolved. PR11360
4215 // We also want it in case variables are used in if/case expressions,
4216 // so enable always. PR11366
4217 semantic_pass_const_fold (s
, relaxed_p
);
4220 semantic_pass_dead_control (s
, relaxed_p
);
4230 semantic_pass_optimize2 (systemtap_session
& s
)
4232 // This is run after type inference. We run an outer "relaxation"
4233 // loop that repeats the optimizations until none of them find
4234 // anything to remove.
4238 // Save the old value of suppress_warnings, as we will be changing
4240 save_and_restore
<bool> suppress_warnings(& s
.suppress_warnings
);
4242 bool relaxed_p
= false;
4243 unsigned iterations
= 0;
4246 assert_no_interrupts();
4247 relaxed_p
= true; // until proven otherwise
4249 // If the verbosity is high enough, always print warnings (overrides -w),
4250 // or if not, always suppress warnings for every itteration after the first.
4252 s
.suppress_warnings
= false;
4253 else if (iterations
> 0)
4254 s
.suppress_warnings
= true;
4257 semantic_pass_opt6 (s
, relaxed_p
);
4267 // ------------------------------------------------------------------------
4270 struct autocast_expanding_visitor
: public var_expanding_visitor
4272 typeresolution_info
& ti
;
4273 autocast_expanding_visitor (typeresolution_info
& ti
): ti(ti
) {}
4275 void resolve_functioncall (functioncall
* fc
)
4277 // This is a very limited version of semantic_pass_symbols, but we're
4278 // late in the game at this point. We won't get a chance to optimize,
4279 // but for now the only functions we expect are kernel/user_string from
4280 // pretty-printing, which don't need optimization.
4282 systemtap_session
& s
= ti
.session
;
4283 size_t nfiles
= s
.files
.size();
4285 symresolution_info
sym (s
);
4286 sym
.current_function
= ti
.current_function
;
4287 sym
.current_probe
= ti
.current_probe
;
4290 // NB: synthetic functions get tacked onto the origin file, so we won't
4291 // see them growing s.files[]. Traverse it directly.
4294 functiondecl
* fd
= fc
->referent
;
4295 sym
.current_function
= fd
;
4296 sym
.current_probe
= 0;
4297 fd
->body
->visit (&sym
);
4300 while (nfiles
< s
.files
.size())
4302 stapfile
* dome
= s
.files
[nfiles
++];
4303 for (size_t i
= 0; i
< dome
->functions
.size(); ++i
)
4305 functiondecl
* fd
= dome
->functions
[i
];
4306 sym
.current_function
= fd
;
4307 sym
.current_probe
= 0;
4308 fd
->body
->visit (&sym
);
4309 // NB: not adding to s.functions just yet...
4313 // Add only the direct functions we need.
4314 functioncall_traversing_visitor ftv
;
4316 for (set
<functiondecl
*>::iterator it
= ftv
.seen
.begin();
4317 it
!= ftv
.seen
.end(); ++it
)
4319 functiondecl
* fd
= *it
;
4320 pair
<map
<string
,functiondecl
*>::iterator
,bool> inserted
=
4321 s
.functions
.insert (make_pair (fd
->name
, fd
));
4322 if (!inserted
.second
&& inserted
.first
->second
!= fd
)
4323 throw SEMANTIC_ERROR
4324 (_F("resolved function '%s' conflicts with an existing function",
4325 fd
->name
.c_str()), fc
->tok
);
4329 void visit_autocast_op (autocast_op
* e
)
4331 const bool lvalue
= is_active_lvalue (e
);
4332 const exp_type_ptr
& details
= e
->operand
->type_details
;
4333 if (details
&& !e
->saved_conversion_error
)
4335 functioncall
* fc
= details
->expand (e
, lvalue
);
4338 ti
.num_newly_resolved
++;
4340 resolve_functioncall (fc
);
4343 provide_lvalue_call (fc
);
4349 var_expanding_visitor::visit_autocast_op (e
);
4354 semantic_pass_types (systemtap_session
& s
)
4358 // next pass: type inference
4359 unsigned iterations
= 0;
4360 typeresolution_info
ti (s
);
4362 // Globals never have detailed types.
4363 // If we null them now, then all remaining vardecls can be detailed.
4364 for (unsigned j
=0; j
<s
.globals
.size(); j
++)
4366 vardecl
* gd
= s
.globals
[j
];
4367 if (!gd
->type_details
)
4368 gd
->type_details
= ti
.null_type
;
4371 ti
.assert_resolvability
= false;
4372 // XXX: maybe convert to exception-based error signalling
4375 assert_no_interrupts();
4378 ti
.num_newly_resolved
= 0;
4379 ti
.num_still_unresolved
= 0;
4380 ti
.num_available_autocasts
= 0;
4382 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
4383 it
!= s
.functions
.end(); it
++)
4385 assert_no_interrupts();
4387 functiondecl
* fd
= it
->second
;
4388 ti
.current_probe
= 0;
4389 ti
.current_function
= fd
;
4391 fd
->body
->visit (& ti
);
4392 // NB: we don't have to assert a known type for
4393 // functions here, to permit a "void" function.
4394 // The translator phase will omit the "retvalue".
4396 // if (fd->type == pe_unknown)
4397 // ti.unresolved (fd->tok);
4398 for (unsigned i
=0; i
< fd
->locals
.size(); ++i
)
4399 ti
.check_local (fd
->locals
[i
]);
4401 // Check and run the autocast expanding visitor.
4402 if (ti
.num_available_autocasts
> 0)
4404 autocast_expanding_visitor
aev (ti
);
4405 aev
.replace (fd
->body
);
4406 ti
.num_available_autocasts
= 0;
4410 for (unsigned j
=0; j
<s
.probes
.size(); j
++)
4412 assert_no_interrupts();
4414 derived_probe
* pn
= s
.probes
[j
];
4415 ti
.current_function
= 0;
4416 ti
.current_probe
= pn
;
4418 pn
->body
->visit (& ti
);
4419 for (unsigned i
=0; i
< pn
->locals
.size(); ++i
)
4420 ti
.check_local (pn
->locals
[i
]);
4422 // Check and run the autocast expanding visitor.
4423 if (ti
.num_available_autocasts
> 0)
4425 autocast_expanding_visitor
aev (ti
);
4426 aev
.replace (pn
->body
);
4427 ti
.num_available_autocasts
= 0;
4430 probe_point
* pp
= pn
->sole_location();
4433 ti
.current_function
= 0;
4434 ti
.current_probe
= 0;
4435 ti
.t
= pe_long
; // NB: expected type
4436 pp
->condition
->visit (& ti
);
4440 for (unsigned j
=0; j
<s
.globals
.size(); j
++)
4442 vardecl
* gd
= s
.globals
[j
];
4443 if (gd
->type
== pe_unknown
)
4444 ti
.unresolved (gd
->tok
);
4445 if(gd
->arity
== 0 && gd
->wrap
== true)
4447 throw SEMANTIC_ERROR (_("wrapping not supported for scalars"), gd
->tok
);
4451 if (ti
.num_newly_resolved
== 0) // converged
4453 if (ti
.num_still_unresolved
== 0)
4454 break; // successfully
4455 else if (! ti
.assert_resolvability
)
4457 ti
.assert_resolvability
= true; // last pass, with error msgs
4459 ti
.mismatch_complexity
= 0; // print every kind of mismatch
4462 { // unsuccessful conclusion
4468 ti
.mismatch_complexity
= 0; // reset for next pass
4471 return rc
+ s
.num_errors();
4475 struct exp_type_null
: public exp_type_details
4477 uintptr_t id () const { return 0; }
4478 bool expandable() const { return false; }
4479 functioncall
*expand(autocast_op
*, bool) { return NULL
; }
4482 typeresolution_info::typeresolution_info (systemtap_session
& s
):
4483 session(s
), num_newly_resolved(0), num_still_unresolved(0),
4484 assert_resolvability(false), mismatch_complexity(0),
4485 current_function(0), current_probe(0), t(pe_unknown
),
4486 null_type(new exp_type_null())
4492 typeresolution_info::visit_literal_number (literal_number
* e
)
4494 assert (e
->type
== pe_long
);
4495 if ((t
== e
->type
) || (t
== pe_unknown
))
4498 mismatch (e
->tok
, t
, e
->type
);
4503 typeresolution_info::visit_literal_string (literal_string
* e
)
4505 assert (e
->type
== pe_string
);
4506 if ((t
== e
->type
) || (t
== pe_unknown
))
4509 mismatch (e
->tok
, t
, e
->type
);
4514 typeresolution_info::visit_logical_or_expr (logical_or_expr
*e
)
4516 visit_binary_expression (e
);
4521 typeresolution_info::visit_logical_and_expr (logical_and_expr
*e
)
4523 visit_binary_expression (e
);
4527 typeresolution_info::visit_regex_query (regex_query
*e
)
4529 // NB: result of regex query is an integer!
4530 if (t
== pe_stats
|| t
== pe_string
)
4531 invalid (e
->tok
, t
);
4534 e
->left
->visit (this);
4536 e
->right
->visit (this); // parser ensures this is a literal known at compile time
4538 if (e
->type
== pe_unknown
)
4541 resolved (e
->tok
, e
->type
);
4547 typeresolution_info::visit_comparison (comparison
*e
)
4549 // NB: result of any comparison is an integer!
4550 if (t
== pe_stats
|| t
== pe_string
)
4551 invalid (e
->tok
, t
);
4553 t
= (e
->right
->type
!= pe_unknown
) ? e
->right
->type
: pe_unknown
;
4554 e
->left
->visit (this);
4555 t
= (e
->left
->type
!= pe_unknown
) ? e
->left
->type
: pe_unknown
;
4556 e
->right
->visit (this);
4558 if (e
->left
->type
!= pe_unknown
&&
4559 e
->right
->type
!= pe_unknown
&&
4560 e
->left
->type
!= e
->right
->type
)
4563 if (e
->type
== pe_unknown
)
4566 resolved (e
->tok
, e
->type
);
4572 typeresolution_info::visit_concatenation (concatenation
*e
)
4574 if (t
!= pe_unknown
&& t
!= pe_string
)
4575 invalid (e
->tok
, t
);
4578 e
->left
->visit (this);
4580 e
->right
->visit (this);
4582 if (e
->type
== pe_unknown
)
4584 e
->type
= pe_string
;
4585 resolved (e
->tok
, e
->type
);
4591 typeresolution_info::visit_assignment (assignment
*e
)
4594 invalid (e
->tok
, t
);
4596 if (e
->op
== "<<<") // stats aggregation
4599 invalid (e
->tok
, t
);
4602 e
->left
->visit (this);
4604 e
->right
->visit (this);
4605 if (e
->type
== pe_unknown
||
4606 e
->type
== pe_stats
)
4609 resolved (e
->tok
, e
->type
);
4613 else if (e
->left
->type
== pe_stats
)
4614 invalid (e
->left
->tok
, e
->left
->type
);
4616 else if (e
->right
->type
== pe_stats
)
4617 invalid (e
->right
->tok
, e
->right
->type
);
4619 else if (e
->op
== "+=" || // numeric only
4631 visit_binary_expression (e
);
4633 else if (e
->op
== ".=" || // string only
4636 if (t
== pe_long
|| t
== pe_stats
)
4637 invalid (e
->tok
, t
);
4640 e
->left
->visit (this);
4642 e
->right
->visit (this);
4643 if (e
->type
== pe_unknown
)
4645 e
->type
= pe_string
;
4646 resolved (e
->tok
, e
->type
);
4649 else if (e
->op
== "=") // overloaded = for string & numeric operands
4651 // logic similar to ternary_expression
4652 exp_type sub_type
= t
;
4654 // Infer types across the l/r values
4655 if (sub_type
== pe_unknown
&& e
->type
!= pe_unknown
)
4658 t
= (sub_type
!= pe_unknown
) ? sub_type
:
4659 (e
->right
->type
!= pe_unknown
) ? e
->right
->type
:
4661 e
->left
->visit (this);
4662 t
= (sub_type
!= pe_unknown
) ? sub_type
:
4663 (e
->left
->type
!= pe_unknown
) ? e
->left
->type
:
4665 e
->right
->visit (this);
4667 if ((sub_type
!= pe_unknown
) && (e
->type
== pe_unknown
))
4670 resolved (e
->tok
, e
->type
);
4672 if ((sub_type
== pe_unknown
) && (e
->left
->type
!= pe_unknown
))
4674 e
->type
= e
->left
->type
;
4675 resolved (e
->tok
, e
->type
);
4678 if (e
->left
->type
!= pe_unknown
&&
4679 e
->right
->type
!= pe_unknown
&&
4680 e
->left
->type
!= e
->right
->type
)
4683 // Propagate type details from the RHS to the assignment
4684 if (e
->type
== e
->right
->type
&&
4685 e
->right
->type_details
&& !e
->type_details
)
4686 resolved_details(e
->right
->type_details
, e
->type_details
);
4688 // Propagate type details from the assignment to the LHS
4689 if (e
->type
== e
->left
->type
&& e
->type_details
)
4691 if (e
->left
->type_details
&&
4692 *e
->left
->type_details
!= *e
->type_details
&&
4693 *e
->left
->type_details
!= *null_type
)
4694 resolved_details(null_type
, e
->left
->type_details
);
4695 else if (!e
->left
->type_details
)
4696 resolved_details(e
->type_details
, e
->left
->type_details
);
4700 throw SEMANTIC_ERROR (_("unsupported assignment operator ") + e
->op
);
4705 typeresolution_info::visit_embedded_expr (embedded_expr
*e
)
4707 if (e
->type
== pe_unknown
)
4709 if (e
->code
.find ("/* string */") != string::npos
)
4710 e
->type
= pe_string
;
4711 else // if (e->code.find ("/* long */") != string::npos)
4714 resolved (e
->tok
, e
->type
);
4720 typeresolution_info::visit_binary_expression (binary_expression
* e
)
4722 if (t
== pe_stats
|| t
== pe_string
)
4723 invalid (e
->tok
, t
);
4726 e
->left
->visit (this);
4728 e
->right
->visit (this);
4730 if (e
->left
->type
!= pe_unknown
&&
4731 e
->right
->type
!= pe_unknown
&&
4732 e
->left
->type
!= e
->right
->type
)
4735 if (e
->type
== pe_unknown
)
4738 resolved (e
->tok
, e
->type
);
4744 typeresolution_info::visit_pre_crement (pre_crement
*e
)
4746 visit_unary_expression (e
);
4751 typeresolution_info::visit_post_crement (post_crement
*e
)
4753 visit_unary_expression (e
);
4758 typeresolution_info::visit_unary_expression (unary_expression
* e
)
4760 if (t
== pe_stats
|| t
== pe_string
)
4761 invalid (e
->tok
, t
);
4764 e
->operand
->visit (this);
4766 if (e
->type
== pe_unknown
)
4769 resolved (e
->tok
, e
->type
);
4775 typeresolution_info::visit_ternary_expression (ternary_expression
* e
)
4777 exp_type sub_type
= t
;
4780 e
->cond
->visit (this);
4782 // Infer types across the true/false arms of the ternary expression.
4784 if (sub_type
== pe_unknown
&& e
->type
!= pe_unknown
)
4787 e
->truevalue
->visit (this);
4789 e
->falsevalue
->visit (this);
4791 if ((sub_type
== pe_unknown
) && (e
->type
!= pe_unknown
))
4792 ; // already resolved
4793 else if ((sub_type
!= pe_unknown
) && (e
->type
== pe_unknown
))
4796 resolved (e
->tok
, e
->type
);
4798 else if ((sub_type
== pe_unknown
) && (e
->truevalue
->type
!= pe_unknown
))
4800 e
->type
= e
->truevalue
->type
;
4801 resolved (e
->tok
, e
->type
);
4803 else if ((sub_type
== pe_unknown
) && (e
->falsevalue
->type
!= pe_unknown
))
4805 e
->type
= e
->falsevalue
->type
;
4806 resolved (e
->tok
, e
->type
);
4808 else if (e
->type
!= sub_type
)
4809 mismatch (e
->tok
, sub_type
, e
->type
);
4811 // Propagate type details from both true/false branches
4812 if (!e
->type_details
&&
4813 e
->type
== e
->truevalue
->type
&& e
->type
== e
->falsevalue
->type
&&
4814 e
->truevalue
->type_details
&& e
->falsevalue
->type_details
&&
4815 *e
->truevalue
->type_details
== *e
->falsevalue
->type_details
)
4816 resolved_details(e
->truevalue
->type_details
, e
->type_details
);
4820 template <class Referrer
, class Referent
>
4821 void resolve_2types (Referrer
* referrer
, Referent
* referent
,
4822 typeresolution_info
* r
, exp_type t
, bool accept_unknown
= false)
4824 exp_type
& re_type
= referrer
->type
;
4825 const token
* re_tok
= referrer
->tok
;
4826 exp_type
& te_type
= referent
->type
;
4828 if (t
!= pe_unknown
&& re_type
== t
&& re_type
== te_type
)
4829 ; // do nothing: all three e->types in agreement
4830 else if (t
== pe_unknown
&& re_type
!= pe_unknown
&& re_type
== te_type
)
4831 ; // do nothing: two known e->types in agreement
4832 else if (re_type
!= pe_unknown
&& te_type
!= pe_unknown
&& re_type
!= te_type
)
4833 r
->mismatch (re_tok
, re_type
, referent
); // referrer-referent
4834 else if (re_type
!= pe_unknown
&& t
!= pe_unknown
&& re_type
!= t
)
4835 r
->mismatch (re_tok
, t
, referent
); // referrer-t
4836 else if (te_type
!= pe_unknown
&& t
!= pe_unknown
&& te_type
!= t
)
4837 r
->mismatch (re_tok
, t
, referent
); // referent-t
4838 else if (re_type
== pe_unknown
&& t
!= pe_unknown
)
4840 // propagate from upstream
4842 r
->resolved (re_tok
, re_type
);
4843 // catch re_type/te_type mismatch later
4845 else if (re_type
== pe_unknown
&& te_type
!= pe_unknown
)
4847 // propagate from referent
4849 r
->resolved (re_tok
, re_type
);
4850 // catch re_type/t mismatch later
4852 else if (re_type
!= pe_unknown
&& te_type
== pe_unknown
)
4854 // propagate to referent
4856 r
->resolved (re_tok
, re_type
, referent
);
4857 // catch re_type/t mismatch later
4859 else if (! accept_unknown
)
4860 r
->unresolved (re_tok
);
4865 typeresolution_info::visit_symbol (symbol
* e
)
4867 if (e
->referent
== 0)
4868 throw SEMANTIC_ERROR (_F("internal error: unresolved symbol '%s'",
4869 e
->name
.c_str()), e
->tok
);
4871 resolve_2types (e
, e
->referent
, this, t
);
4873 if (e
->type
== e
->referent
->type
)
4875 // If both have type details, then they either must agree;
4876 // otherwise force them both to null.
4877 if (e
->type_details
&& e
->referent
->type_details
&&
4878 *e
->type_details
!= *e
->referent
->type_details
)
4880 resolved_details(null_type
, e
->type_details
);
4881 resolved_details(null_type
, e
->referent
->type_details
);
4883 else if (e
->type_details
&& !e
->referent
->type_details
)
4884 resolved_details(e
->type_details
, e
->referent
->type_details
);
4885 else if (!e
->type_details
&& e
->referent
->type_details
)
4886 resolved_details(e
->referent
->type_details
, e
->type_details
);
4892 typeresolution_info::visit_target_symbol (target_symbol
* e
)
4894 // This occurs only if a target symbol was not resolved over in
4895 // tapset.cxx land, that error was properly suppressed, and the
4896 // later unused-expression-elimination pass didn't get rid of it
4897 // either. So we have a target symbol that is believed to be of
4898 // genuine use, yet unresolved by the provider.
4900 if (session
.verbose
> 2)
4902 clog
<< _("Resolution problem with ");
4903 if (current_function
)
4905 clog
<< "function " << current_function
->name
<< endl
;
4906 current_function
->body
->print (clog
);
4909 else if (current_probe
)
4911 clog
<< "probe " << *current_probe
->sole_location() << endl
;
4912 current_probe
->body
->print (clog
);
4916 //TRANSLATORS: simply saying not an issue with a probe or function
4917 clog
<< _("other") << endl
;
4920 if (e
->saved_conversion_error
)
4921 throw (* (e
->saved_conversion_error
));
4923 throw SEMANTIC_ERROR(_("unresolved target-symbol expression"), e
->tok
);
4928 typeresolution_info::visit_atvar_op (atvar_op
* e
)
4930 // This occurs only if an @var() was not resolved over in
4931 // tapset.cxx land, that error was properly suppressed, and the
4932 // later unused-expression-elimination pass didn't get rid of it
4933 // either. So we have an @var() that is believed to be of
4934 // genuine use, yet unresolved by the provider.
4936 if (session
.verbose
> 2)
4938 clog
<< _("Resolution problem with ");
4939 if (current_function
)
4941 clog
<< "function " << current_function
->name
<< endl
;
4942 current_function
->body
->print (clog
);
4945 else if (current_probe
)
4947 clog
<< "probe " << *current_probe
->sole_location() << endl
;
4948 current_probe
->body
->print (clog
);
4952 //TRANSLATORS: simply saying not an issue with a probe or function
4953 clog
<< _("other") << endl
;
4956 if (e
->saved_conversion_error
)
4957 throw (* (e
->saved_conversion_error
));
4959 throw SEMANTIC_ERROR(_("unresolved @var() expression"), e
->tok
);
4964 typeresolution_info::visit_defined_op (defined_op
* e
)
4966 throw SEMANTIC_ERROR(_("unexpected @defined"), e
->tok
);
4971 typeresolution_info::visit_entry_op (entry_op
* e
)
4973 throw SEMANTIC_ERROR(_("@entry is only valid in .return probes"), e
->tok
);
4978 typeresolution_info::visit_cast_op (cast_op
* e
)
4980 // Like target_symbol, a cast_op shouldn't survive this far
4981 // unless it was not resolved and its value is really needed.
4982 if (e
->saved_conversion_error
)
4983 throw (* (e
->saved_conversion_error
));
4985 throw SEMANTIC_ERROR(_F("type definition '%s' not found in '%s'",
4986 e
->type_name
.c_str(), e
->module
.c_str()), e
->tok
);
4991 typeresolution_info::visit_autocast_op (autocast_op
* e
)
4993 // Like cast_op, a implicit autocast_op shouldn't survive this far
4994 // unless it was not resolved and its value is really needed.
4995 if (assert_resolvability
&& e
->saved_conversion_error
)
4996 throw (* (e
->saved_conversion_error
));
4997 else if (assert_resolvability
)
4998 throw SEMANTIC_ERROR(_("unknown type in dereference"), e
->tok
);
5001 e
->operand
->visit (this);
5003 num_still_unresolved
++;
5004 if (e
->operand
->type_details
&&
5005 e
->operand
->type_details
->expandable())
5006 num_available_autocasts
++;
5011 typeresolution_info::visit_perf_op (perf_op
* e
)
5013 // A perf_op should already be resolved
5014 if (t
== pe_stats
|| t
== pe_string
)
5015 invalid (e
->tok
, t
);
5019 // (There is no real need to visit our operand - by parser
5020 // construction, it's always a string literal, with its type already
5023 e
->operand
->visit (this);
5028 typeresolution_info::visit_arrayindex (arrayindex
* e
)
5031 symbol
*array
= NULL
;
5032 hist_op
*hist
= NULL
;
5033 classify_indexable(e
->base
, array
, hist
);
5035 // Every hist_op has type [int]:int, that is to say, every hist_op
5036 // is a pseudo-one-dimensional integer array type indexed by
5037 // integers (bucket numbers).
5041 if (e
->indexes
.size() != 1)
5042 unresolved (e
->tok
);
5044 e
->indexes
[0]->visit (this);
5045 if (e
->indexes
[0]->type
!= pe_long
)
5046 unresolved (e
->tok
);
5048 if (e
->type
!= pe_long
)
5051 resolved (e
->tok
, e
->type
);
5056 // Now we are left with "normal" map inference and index checking.
5059 assert (array
->referent
!= 0);
5060 resolve_2types (e
, array
->referent
, this, t
);
5062 // now resolve the array indexes
5064 // if (e->referent->index_types.size() == 0)
5065 // // redesignate referent as array
5066 // e->referent->set_arity (e->indexes.size ());
5068 if (e
->indexes
.size() != array
->referent
->index_types
.size())
5069 unresolved (e
->tok
); // symbol resolution should prevent this
5070 else for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
5074 expression
* ee
= e
->indexes
[i
];
5075 exp_type
& ft
= array
->referent
->index_types
[i
];
5078 exp_type at
= ee
->type
;
5080 if ((at
== pe_string
|| at
== pe_long
) && ft
== pe_unknown
)
5082 // propagate to formal type
5084 resolved (ee
->tok
, ft
, array
->referent
, i
);
5087 invalid (ee
->tok
, at
);
5089 invalid (ee
->tok
, ft
);
5090 if (at
!= pe_unknown
&& ft
!= pe_unknown
&& ft
!= at
)
5091 mismatch (ee
->tok
, ee
->type
, array
->referent
, i
);
5092 if (at
== pe_unknown
)
5093 unresolved (ee
->tok
);
5100 typeresolution_info::visit_functioncall (functioncall
* e
)
5102 if (e
->referent
== 0)
5103 throw SEMANTIC_ERROR (_F("internal error: unresolved function call to '%s'",
5104 e
->function
.c_str()), e
->tok
);
5106 resolve_2types (e
, e
->referent
, this, t
, true); // accept unknown type
5108 if (e
->type
== pe_stats
)
5109 invalid (e
->tok
, e
->type
);
5111 const exp_type_ptr
& func_type
= e
->referent
->type_details
;
5112 if (func_type
&& e
->referent
->type
== e
->type
5113 && (!e
->type_details
|| *func_type
!= *e
->type_details
))
5114 resolved_details(e
->referent
->type_details
, e
->type_details
);
5116 // now resolve the function parameters
5117 if (e
->args
.size() != e
->referent
->formal_args
.size())
5118 unresolved (e
->tok
); // symbol resolution should prevent this
5119 else for (unsigned i
=0; i
<e
->args
.size(); i
++)
5121 expression
* ee
= e
->args
[i
];
5122 exp_type
& ft
= e
->referent
->formal_args
[i
]->type
;
5123 const token
* fe_tok
= e
->referent
->formal_args
[i
]->tok
;
5126 exp_type at
= ee
->type
;
5128 if (((at
== pe_string
) || (at
== pe_long
)) && ft
== pe_unknown
)
5130 // propagate to formal arg
5132 resolved (ee
->tok
, ft
, e
->referent
->formal_args
[i
], i
);
5135 invalid (ee
->tok
, at
);
5137 invalid (fe_tok
, ft
);
5138 if (at
!= pe_unknown
&& ft
!= pe_unknown
&& ft
!= at
)
5139 mismatch (ee
->tok
, ee
->type
, e
->referent
->formal_args
[i
], i
);
5140 if (at
== pe_unknown
)
5141 unresolved (ee
->tok
);
5147 typeresolution_info::visit_block (block
* e
)
5149 for (unsigned i
=0; i
<e
->statements
.size(); i
++)
5152 e
->statements
[i
]->visit (this);
5158 typeresolution_info::visit_try_block (try_block
* e
)
5161 e
->try_block
->visit (this);
5162 if (e
->catch_error_var
)
5165 e
->catch_error_var
->visit (this);
5168 e
->catch_block
->visit (this);
5173 typeresolution_info::visit_embeddedcode (embeddedcode
* s
)
5175 // PR11573. If we have survived thus far with a piece of embedded
5176 // code that requires uprobes, we need to track this.
5178 // This is an odd place for this check, as opposed
5179 // to a separate 'optimization' pass, or c_unparser::visit_embeddedcode
5180 // over yonder in pass 3. However, we want to do it during pass 2 so
5181 // that cached sessions also get the uprobes treatment.
5182 if (! session
.need_uprobes
5183 && s
->code
.find("/* pragma:uprobes */") != string::npos
)
5185 if (session
.verbose
> 2)
5186 clog
<< _("Activating uprobes support because /* pragma:uprobes */ seen.") << endl
;
5187 session
.need_uprobes
= true;
5190 // PR15065. Likewise, we need to detect /* pragma:tagged_dfa */
5191 // before the gen_dfa_table pass. Again, the typechecking part of
5192 // pass 2 is a good place for this.
5193 if (! session
.need_tagged_dfa
5194 && s
->code
.find("/* pragma:tagged_dfa */") != string::npos
)
5196 // if (session.verbose > 2)
5197 // clog << _F("Turning on DFA subexpressions, pragma:tagged_dfa found in %s",
5198 // current_function->name.c_str()) << endl;
5199 // session.need_tagged_dfa = true;
5200 throw SEMANTIC_ERROR (_("Tagged DFA support is not yet available"), s
->tok
);
5206 typeresolution_info::visit_if_statement (if_statement
* e
)
5209 e
->condition
->visit (this);
5212 e
->thenblock
->visit (this);
5217 e
->elseblock
->visit (this);
5223 typeresolution_info::visit_for_loop (for_loop
* e
)
5226 if (e
->init
) e
->init
->visit (this);
5228 e
->cond
->visit (this);
5230 if (e
->incr
) e
->incr
->visit (this);
5232 e
->block
->visit (this);
5237 typeresolution_info::visit_foreach_loop (foreach_loop
* e
)
5239 // See also visit_arrayindex.
5240 // This is different in that, being a statement, we can't assign
5241 // a type to the outer array, only propagate to/from the indexes
5243 // if (e->referent->index_types.size() == 0)
5244 // // redesignate referent as array
5245 // e->referent->set_arity (e->indexes.size ());
5247 exp_type wanted_value
= pe_unknown
;
5248 symbol
*array
= NULL
;
5249 hist_op
*hist
= NULL
;
5250 classify_indexable(e
->base
, array
, hist
);
5254 if (e
->indexes
.size() != 1)
5255 unresolved (e
->tok
);
5257 e
->indexes
[0]->visit (this);
5258 if (e
->indexes
[0]->type
!= pe_long
)
5259 unresolved (e
->tok
);
5261 wanted_value
= pe_long
;
5266 if (e
->indexes
.size() != array
->referent
->index_types
.size())
5267 unresolved (e
->tok
); // symbol resolution should prevent this
5270 for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
5272 expression
* ee
= e
->indexes
[i
];
5273 exp_type
& ft
= array
->referent
->index_types
[i
];
5276 exp_type at
= ee
->type
;
5278 if ((at
== pe_string
|| at
== pe_long
) && ft
== pe_unknown
)
5280 // propagate to formal type
5282 resolved (ee
->tok
, ee
->type
, array
->referent
, i
);
5285 invalid (ee
->tok
, at
);
5287 invalid (ee
->tok
, ft
);
5288 if (at
!= pe_unknown
&& ft
!= pe_unknown
&& ft
!= at
)
5289 mismatch (ee
->tok
, ee
->type
, array
->referent
, i
);
5290 if (at
== pe_unknown
)
5291 unresolved (ee
->tok
);
5293 for (unsigned i
=0; i
<e
->array_slice
.size(); i
++)
5294 if (e
->array_slice
[i
])
5296 expression
* ee
= e
->array_slice
[i
];
5297 exp_type
& ft
= array
->referent
->index_types
[i
];
5300 exp_type at
= ee
->type
;
5302 if ((at
== pe_string
|| at
== pe_long
) && ft
== pe_unknown
)
5304 // propagate to formal type
5306 resolved (ee
->tok
, ee
->type
, array
->referent
, i
);
5309 invalid (ee
->tok
, at
);
5311 invalid (ee
->tok
, ft
);
5312 if (at
!= pe_unknown
&& ft
!= pe_unknown
&& ft
!= at
)
5313 mismatch (ee
->tok
, ee
->type
, array
->referent
, i
);
5314 if (at
== pe_unknown
)
5315 unresolved (ee
->tok
);
5319 array
->visit (this);
5320 wanted_value
= array
->type
;
5325 if (wanted_value
== pe_stats
)
5326 invalid(e
->value
->tok
, wanted_value
);
5327 else if (wanted_value
!= pe_unknown
)
5328 check_arg_type(wanted_value
, e
->value
);
5332 e
->value
->visit (this);
5336 /* Prevent @sum etc. aggregate sorting on non-statistics arrays. */
5337 if (wanted_value
!= pe_unknown
)
5338 if (e
->sort_aggr
!= sc_none
&& wanted_value
!= pe_stats
)
5339 invalid (array
->tok
, wanted_value
);
5344 e
->limit
->visit (this);
5348 e
->block
->visit (this);
5353 typeresolution_info::visit_null_statement (null_statement
*)
5359 typeresolution_info::visit_expr_statement (expr_statement
* e
)
5362 e
->value
->visit (this);
5366 struct delete_statement_typeresolution_info
:
5367 public throwing_visitor
5369 typeresolution_info
*parent
;
5370 delete_statement_typeresolution_info (typeresolution_info
*p
):
5371 throwing_visitor (_("invalid operand of delete expression")),
5375 void visit_arrayindex (arrayindex
* e
)
5377 parent
->visit_arrayindex (e
);
5380 void visit_symbol (symbol
* e
)
5382 exp_type ignored
= pe_unknown
;
5383 assert (e
->referent
!= 0);
5384 resolve_2types (e
, e
->referent
, parent
, ignored
);
5390 typeresolution_info::visit_delete_statement (delete_statement
* e
)
5392 delete_statement_typeresolution_info
di (this);
5394 e
->value
->visit (&di
);
5399 typeresolution_info::visit_next_statement (next_statement
*)
5405 typeresolution_info::visit_break_statement (break_statement
*)
5411 typeresolution_info::visit_continue_statement (continue_statement
*)
5417 typeresolution_info::visit_array_in (array_in
* e
)
5419 // all unary operators only work on numerics
5421 t
= pe_unknown
; // array value can be anything
5422 e
->operand
->visit (this);
5424 if (t1
== pe_unknown
&& e
->type
!= pe_unknown
)
5425 ; // already resolved
5426 else if (t1
== pe_string
|| t1
== pe_stats
)
5427 mismatch (e
->tok
, t1
, pe_long
);
5428 else if (e
->type
== pe_unknown
)
5431 resolved (e
->tok
, e
->type
);
5437 typeresolution_info::visit_return_statement (return_statement
* e
)
5439 // This is like symbol, where the referent is
5440 // the return value of the function.
5442 // translation pass will print error
5443 if (current_function
== 0)
5446 exp_type
& e_type
= current_function
->type
;
5447 t
= current_function
->type
;
5448 e
->value
->visit (this);
5450 if (e_type
!= pe_unknown
&& e
->value
->type
!= pe_unknown
5451 && e_type
!= e
->value
->type
)
5452 mismatch (e
->value
->tok
, e
->value
->type
, current_function
);
5453 if (e_type
== pe_unknown
&&
5454 (e
->value
->type
== pe_long
|| e
->value
->type
== pe_string
))
5456 // propagate non-statistics from value
5457 e_type
= e
->value
->type
;
5458 resolved (e
->value
->tok
, e_type
, current_function
);
5460 if (e
->value
->type
== pe_stats
)
5461 invalid (e
->value
->tok
, e
->value
->type
);
5463 const exp_type_ptr
& value_type
= e
->value
->type_details
;
5464 if (value_type
&& current_function
->type
== e
->value
->type
)
5466 exp_type_ptr
& func_type
= current_function
->type_details
;
5468 // The function can take on the type details of the return value.
5469 resolved_details(value_type
, func_type
);
5470 else if (*func_type
!= *value_type
&& *func_type
!= *null_type
)
5471 // Conflicting return types? NO TYPE FOR YOU!
5472 resolved_details(null_type
, func_type
);
5477 typeresolution_info::visit_print_format (print_format
* e
)
5479 size_t unresolved_args
= 0;
5483 e
->hist
->visit(this);
5486 else if (e
->print_with_format
)
5488 // If there's a format string, we can do both inference *and*
5491 // First we extract the subsequence of formatting components
5492 // which are conversions (not just literal string components)
5494 unsigned expected_num_args
= 0;
5495 std::vector
<print_format::format_component
> components
;
5496 for (size_t i
= 0; i
< e
->components
.size(); ++i
)
5498 if (e
->components
[i
].type
== print_format::conv_unspecified
)
5499 throw SEMANTIC_ERROR (_("Unspecified conversion in print operator format string"),
5501 else if (e
->components
[i
].type
== print_format::conv_literal
)
5503 components
.push_back(e
->components
[i
]);
5504 ++expected_num_args
;
5505 if (e
->components
[i
].widthtype
== print_format::width_dynamic
)
5506 ++expected_num_args
;
5507 if (e
->components
[i
].prectype
== print_format::prec_dynamic
)
5508 ++expected_num_args
;
5511 // Then we check that the number of conversions and the number
5514 if (expected_num_args
!= e
->args
.size())
5515 throw SEMANTIC_ERROR (_("Wrong number of args to formatted print operator"),
5518 // Then we check that the types of the conversions match the types
5521 for (size_t i
= 0; i
< components
.size(); ++i
)
5523 // Check the dynamic width, if specified
5524 if (components
[i
].widthtype
== print_format::width_dynamic
)
5526 check_arg_type (pe_long
, e
->args
[argno
]);
5530 // Check the dynamic precision, if specified
5531 if (components
[i
].prectype
== print_format::prec_dynamic
)
5533 check_arg_type (pe_long
, e
->args
[argno
]);
5537 exp_type wanted
= pe_unknown
;
5539 switch (components
[i
].type
)
5541 case print_format::conv_unspecified
:
5542 case print_format::conv_literal
:
5546 case print_format::conv_pointer
:
5547 case print_format::conv_number
:
5548 case print_format::conv_binary
:
5549 case print_format::conv_char
:
5550 case print_format::conv_memory
:
5551 case print_format::conv_memory_hex
:
5555 case print_format::conv_string
:
5560 assert (wanted
!= pe_unknown
);
5561 check_arg_type (wanted
, e
->args
[argno
]);
5567 // Without a format string, the best we can do is require that
5568 // each argument resolve to a concrete type.
5569 for (size_t i
= 0; i
< e
->args
.size(); ++i
)
5572 e
->args
[i
]->visit (this);
5573 if (e
->args
[i
]->type
== pe_unknown
)
5575 unresolved (e
->args
[i
]->tok
);
5581 if (unresolved_args
== 0)
5583 if (e
->type
== pe_unknown
)
5585 if (e
->print_to_stream
)
5588 e
->type
= pe_string
;
5589 resolved (e
->tok
, e
->type
);
5594 e
->type
= pe_unknown
;
5595 unresolved (e
->tok
);
5601 typeresolution_info::visit_stat_op (stat_op
* e
)
5604 e
->stat
->visit (this);
5605 if (e
->type
== pe_unknown
)
5608 resolved (e
->tok
, e
->type
);
5610 else if (e
->type
!= pe_long
)
5611 mismatch (e
->tok
, pe_long
, e
->type
);
5615 typeresolution_info::visit_hist_op (hist_op
* e
)
5618 e
->stat
->visit (this);
5623 typeresolution_info::check_arg_type (exp_type wanted
, expression
* arg
)
5628 if (arg
->type
== pe_unknown
)
5631 resolved (arg
->tok
, arg
->type
);
5633 else if (arg
->type
!= wanted
)
5635 mismatch (arg
->tok
, wanted
, arg
->type
);
5641 typeresolution_info::check_local (vardecl
* v
)
5645 num_still_unresolved
++;
5646 if (assert_resolvability
)
5648 (SEMANTIC_ERROR (_("array locals not supported, missing global declaration? "), v
->tok
));
5651 if (v
->type
== pe_unknown
)
5652 unresolved (v
->tok
);
5653 else if (v
->type
== pe_stats
)
5655 num_still_unresolved
++;
5656 if (assert_resolvability
)
5658 (SEMANTIC_ERROR (_("stat locals not supported, missing global declaration? "), v
->tok
));
5660 else if (!(v
->type
== pe_long
|| v
->type
== pe_string
))
5661 invalid (v
->tok
, v
->type
);
5666 typeresolution_info::unresolved (const token
* tok
)
5668 num_still_unresolved
++;
5670 if (assert_resolvability
&& mismatch_complexity
<= 0)
5673 msg
<< _("unresolved type ");
5674 session
.print_error (SEMANTIC_ERROR (msg
.str(), tok
));
5680 typeresolution_info::invalid (const token
* tok
, exp_type pe
)
5682 num_still_unresolved
++;
5684 if (assert_resolvability
)
5687 if (tok
&& tok
->type
== tok_operator
)
5688 msg
<< _("invalid operator");
5690 msg
<< _("invalid type ") << pe
;
5691 session
.print_error (SEMANTIC_ERROR (msg
.str(), tok
));
5696 typeresolution_info::mismatch (const binary_expression
* e
)
5698 num_still_unresolved
++;
5700 if (assert_resolvability
&& mismatch_complexity
<= 1)
5703 msg
<< _F("type mismatch: left and right sides don't agree (%s vs %s)",
5704 lex_cast(e
->left
->type
).c_str(), lex_cast(e
->right
->type
).c_str());
5705 session
.print_error (SEMANTIC_ERROR (msg
.str(), e
->tok
));
5707 else if (!assert_resolvability
)
5708 mismatch_complexity
= max(1, mismatch_complexity
);
5711 /* tok token where mismatch occurred
5712 * t1 type we expected (the 'good' type)
5713 * t2 type we received (the 'bad' type)
5716 typeresolution_info::mismatch (const token
* tok
, exp_type t1
, exp_type t2
)
5718 num_still_unresolved
++;
5720 if (assert_resolvability
&& mismatch_complexity
<= 2)
5723 msg
<< _F("type mismatch: expected %s", lex_cast(t1
).c_str());
5724 if (t2
!= pe_unknown
)
5725 msg
<< _F(" but found %s", lex_cast(t2
).c_str());
5726 session
.print_error (SEMANTIC_ERROR (msg
.str(), tok
));
5728 else if (!assert_resolvability
)
5729 mismatch_complexity
= max(2, mismatch_complexity
);
5732 /* tok token where the mismatch happened
5733 * type type we received (the 'bad' type)
5734 * decl declaration of mismatched symbol
5735 * index if index-based (array index or function arg)
5738 typeresolution_info::mismatch (const token
*tok
, exp_type type
,
5739 const symboldecl
* decl
, int index
)
5741 num_still_unresolved
++;
5743 if (assert_resolvability
&& mismatch_complexity
<= 3)
5745 assert(decl
!= NULL
);
5747 // If mismatch is against a function parameter from within the function
5748 // itself (rather than a function call), then the index will be -1. We
5749 // check here if the decl corresponds to one of the params and if so,
5750 // adjust the index.
5751 if (current_function
!= NULL
&& index
== -1)
5753 vector
<vardecl
*>& args
= current_function
->formal_args
;
5754 for (unsigned i
= 0; i
< args
.size() && index
< 0; i
++)
5755 if (args
[i
] == decl
)
5759 // get the declaration's original type and token
5760 const resolved_type
*original
= NULL
;
5761 for (vector
<resolved_type
>::const_iterator it
= resolved_types
.begin();
5762 it
!= resolved_types
.end() && original
== NULL
; ++it
)
5764 if (it
->decl
== decl
&& it
->index
== index
)
5768 // print basic mismatch msg if we couldn't find the decl (this can happen
5769 // for explicitly typed decls e.g. myvar:long or for fabricated (already
5770 // resolved) decls e.g. __perf_read_*)
5771 if (original
== NULL
)
5773 session
.print_error (SEMANTIC_ERROR (
5774 _F("type mismatch: expected %s but found %s",
5775 lex_cast(type
).c_str(),
5776 lex_cast(decl
->type
).c_str()),
5781 // print where mismatch happened and chain with origin of decl type
5786 msg
<< _F("index %d ", index
);
5787 msg
<< _F("type mismatch (%s)", lex_cast(type
).c_str());
5788 semantic_error
err(ERR_SRC
, msg
.str(), tok
);
5790 stringstream chain_msg
;
5791 chain_msg
<< _("type");
5793 chain_msg
<< _F(" of index %d", index
);
5794 chain_msg
<< _F(" was first inferred here (%s)",
5795 lex_cast(decl
->type
).c_str());
5796 semantic_error
chain(ERR_SRC
, chain_msg
.str(), original
->tok
);
5798 err
.set_chain(chain
);
5799 session
.print_error (err
);
5801 else if (!assert_resolvability
)
5802 mismatch_complexity
= max(3, mismatch_complexity
);
5806 /* tok token where resolution occurred
5807 * type type to which we resolved
5808 * decl declaration of resolved symbol
5809 * index if index-based (array index or function arg)
5812 typeresolution_info::resolved (const token
*tok
, exp_type type
,
5813 const symboldecl
* decl
, int index
)
5815 num_newly_resolved
++;
5817 // We only use the resolved_types vector to give better mismatch messages
5818 // involving symbols. So don't bother adding it if we're not given a decl
5821 // As a fail-safe, if the decl & index is already in the vector, then
5822 // modify it instead of adding another one to ensure uniqueness. This
5823 // should never happen since we only call resolved once for each decl &
5824 // index, but better safe than sorry. (IE. if it does happen, better have
5825 // the latest resolution info for better mismatch reporting later).
5826 for (unsigned i
= 0; i
< resolved_types
.size(); i
++)
5828 if (resolved_types
[i
].decl
== decl
5829 && resolved_types
[i
].index
== index
)
5831 resolved_types
[i
].tok
= tok
;
5835 resolved_type
res(tok
, decl
, index
);
5836 resolved_types
.push_back(res
);
5841 typeresolution_info::resolved_details (const exp_type_ptr
& src
,
5844 num_newly_resolved
++;
5848 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */