1 : // -*- C++ -*-
2 : // Copyright (C) 2005-2008 Red Hat Inc.
3 : //
4 : // This file is part of systemtap, and is free software. You can
5 : // redistribute it and/or modify it under the terms of the GNU General
6 : // Public License (GPL); either version 2, or (at your option) any
7 : // later version.
8 :
9 : #ifndef ELABORATE_H
10 : #define ELABORATE_H
11 :
12 : #include "staptree.h"
13 : #include "parse.h"
14 : #include <string>
15 : #include <vector>
16 : #include <iostream>
17 : #include <sstream>
18 : #include <map>
19 :
20 : // ------------------------------------------------------------------------
21 :
22 : struct derived_probe;
23 : struct match_node;
24 :
25 : struct symresolution_info: public traversing_visitor
26 485 : {
27 : protected:
28 : systemtap_session& session;
29 :
30 : public:
31 : functiondecl* current_function;
32 : derived_probe* current_probe;
33 : symresolution_info (systemtap_session& s);
34 :
35 : vardecl* find_var (const std::string& name, int arity);
36 : functiondecl* find_function (const std::string& name, unsigned arity);
37 :
38 : void visit_block (block *s);
39 : void visit_symbol (symbol* e);
40 : void visit_foreach_loop (foreach_loop* e);
41 : void visit_arrayindex (arrayindex* e);
42 : void visit_functioncall (functioncall* e);
43 : void visit_delete_statement (delete_statement* s);
44 : };
45 :
46 :
47 : struct typeresolution_info: public visitor
48 432 : {
49 : typeresolution_info (systemtap_session& s);
50 : systemtap_session& session;
51 : unsigned num_newly_resolved;
52 : unsigned num_still_unresolved;
53 : bool assert_resolvability;
54 : functiondecl* current_function;
55 : derived_probe* current_probe;
56 :
57 : void check_arg_type (exp_type wanted, expression* arg);
58 : void mismatch (const token* tok, exp_type t1, exp_type t2);
59 : void unresolved (const token* tok);
60 : void resolved (const token* tok, exp_type t);
61 : void invalid (const token* tok, exp_type t);
62 :
63 : exp_type t; // implicit parameter for nested visit call; may clobber
64 :
65 : void visit_block (block* s);
66 : void visit_embeddedcode (embeddedcode* s);
67 : void visit_null_statement (null_statement* s);
68 : void visit_expr_statement (expr_statement* s);
69 : void visit_if_statement (if_statement* s);
70 : void visit_for_loop (for_loop* s);
71 : void visit_foreach_loop (foreach_loop* s);
72 : void visit_return_statement (return_statement* s);
73 : void visit_delete_statement (delete_statement* s);
74 : void visit_next_statement (next_statement* s);
75 : void visit_break_statement (break_statement* s);
76 : void visit_continue_statement (continue_statement* s);
77 : void visit_literal_string (literal_string* e);
78 : void visit_literal_number (literal_number* e);
79 : void visit_binary_expression (binary_expression* e);
80 : void visit_unary_expression (unary_expression* e);
81 : void visit_pre_crement (pre_crement* e);
82 : void visit_post_crement (post_crement* e);
83 : void visit_logical_or_expr (logical_or_expr* e);
84 : void visit_logical_and_expr (logical_and_expr* e);
85 : void visit_array_in (array_in* e);
86 : void visit_comparison (comparison* e);
87 : void visit_concatenation (concatenation* e);
88 : void visit_ternary_expression (ternary_expression* e);
89 : void visit_assignment (assignment* e);
90 : void visit_symbol (symbol* e);
91 : void visit_target_symbol (target_symbol* e);
92 : void visit_arrayindex (arrayindex* e);
93 : void visit_functioncall (functioncall* e);
94 : void visit_print_format (print_format* e);
95 : void visit_stat_op (stat_op* e);
96 : void visit_hist_op (hist_op* e);
97 : };
98 :
99 :
100 : // ------------------------------------------------------------------------
101 :
102 :
103 : // A derived_probe is a probe that has been elaborated by
104 : // binding to a matching provider. The locations std::vector
105 : // may be smaller or larger than the base probe, since a
106 : // provider may transform it.
107 :
108 : class translator_output;
109 : class derived_probe_group;
110 :
111 : struct derived_probe: public probe
112 : {
113 : derived_probe (probe* b);
114 : derived_probe (probe* b, probe_point* l);
115 : probe* base; // the original parsed probe
116 66825 : virtual probe* basest () { return base->basest(); }
117 7 : virtual ~derived_probe () {}
118 : virtual void join_group (systemtap_session& s) = 0;
119 : virtual probe_point* sole_location () const;
120 : virtual void printsig (std::ostream &o) const;
121 : void printsig_nested (std::ostream &o) const;
122 : virtual void collect_derivation_chain (std::vector<probe*> &probes_list);
123 :
124 2117 : virtual void emit_probe_context_vars (translator_output*) {}
125 : // From within unparser::emit_common_header, add any extra variables
126 : // to this probe's context locals.
127 :
128 2115 : virtual void initialize_probe_context_vars (translator_output*) {}
129 : // From within unparser::emit_probe, initialized any extra variables
130 : // in this probe's context locals.
131 :
132 : public:
133 : static void emit_common_header (translator_output* o);
134 : // from c_unparser::emit_common_header
135 : // XXX: probably can move this stuff to a probe_group::emit_module_decls
136 :
137 28319 : virtual bool needs_global_locks () { return true; }
138 : // by default, probes need locks around global variables
139 : };
140 :
141 : // ------------------------------------------------------------------------
142 :
143 : struct unparser;
144 :
145 : // Various derived classes derived_probe_group manage the
146 : // registration/invocation/unregistration of sibling probes.
147 : struct derived_probe_group
148 592 : {
149 0 : virtual ~derived_probe_group () {}
150 :
151 : virtual void emit_module_decls (systemtap_session& s) = 0;
152 : // The _decls-generated code may assume that declarations such as
153 : // the context, embedded-C code, function and probe handler bodies
154 : // are all already generated. That is, _decls is called near the
155 : // end of the code generation process. It should minimize the
156 : // number of separate variables (and to a lesser extent, their
157 : // size).
158 :
159 : virtual void emit_module_init (systemtap_session& s) = 0;
160 : // The _init-generated code may assume that it is called only once.
161 : // If that code fails at run time, it must set rc=1 and roll back
162 : // any partial initializations, for its _exit friend will NOT be
163 : // invoked. The generated code may use pre-declared "int i, j;".
164 :
165 : virtual void emit_module_exit (systemtap_session& s) = 0;
166 : // The _exit-generated code may assume that it is executed exactly
167 : // zero times (if the _init-generated code failed) or once. (_exit
168 : // itself may be called a few times, to generate the code in a few
169 : // different places in the probe module.)
170 : // The generated code may use pre-declared "int i, j;".
171 : };
172 :
173 :
174 : // ------------------------------------------------------------------------
175 :
176 : struct derived_probe_builder
177 524822 : {
178 : virtual void build(systemtap_session & sess,
179 : probe* base,
180 : probe_point* location,
181 : std::map<std::string, literal*> const & parameters,
182 : std::vector<derived_probe*> & finished_results) = 0;
183 0 : virtual ~derived_probe_builder() {}
184 531000 : virtual void build_no_more (systemtap_session &) {}
185 :
186 : static bool has_null_param (std::map<std::string, literal*> const & parameters,
187 : const std::string& key);
188 : static bool get_param (std::map<std::string, literal*> const & parameters,
189 : const std::string& key, std::string& value);
190 : static bool get_param (std::map<std::string, literal*> const & parameters,
191 : const std::string& key, int64_t& value);
192 : };
193 :
194 :
195 : struct
196 : match_key
197 5598558 : {
198 : std::string name;
199 : bool have_parameter;
200 : exp_type parameter_type;
201 :
202 : match_key(std::string const & n);
203 : match_key(probe_point::component const & c);
204 :
205 : match_key & with_number();
206 : match_key & with_string();
207 : std::string str() const;
208 : bool operator<(match_key const & other) const;
209 : bool globmatch(match_key const & other) const;
210 : };
211 :
212 :
213 : class
214 : match_node
215 : {
216 : typedef std::map<match_key, match_node*> sub_map_t;
217 : typedef std::map<match_key, match_node*>::iterator sub_map_iterator_t;
218 : sub_map_t sub;
219 : derived_probe_builder* end;
220 :
221 : public:
222 : match_node();
223 :
224 : void find_and_build (systemtap_session& s,
225 : probe* p, probe_point *loc, unsigned pos,
226 : std::vector<derived_probe *>& results);
227 : void build_no_more (systemtap_session &s);
228 :
229 : match_node* bind(match_key const & k);
230 : match_node* bind(std::string const & k);
231 : match_node* bind_str(std::string const & k);
232 : match_node* bind_num(std::string const & k);
233 : void bind(derived_probe_builder* e);
234 : };
235 :
236 : // ------------------------------------------------------------------------
237 :
238 : /* struct systemtap_session moved to session.h */
239 :
240 : int semantic_pass (systemtap_session& s);
241 : void derive_probes (systemtap_session& s,
242 : probe *p, std::vector<derived_probe*>& dps,
243 : bool optional = false);
244 :
245 : // A helper we use here and in translate, for pulling symbols out of lvalue
246 : // expressions.
247 : symbol * get_symbol_within_expression (expression *e);
248 :
249 :
250 : struct unparser;
251 :
252 :
253 : #endif // ELABORATE_H
|