summaryrefslogtreecommitdiffstats
path: root/staptree.h
diff options
context:
space:
mode:
authorgraydon <graydon>2005-11-14 04:39:47 +0000
committergraydon <graydon>2005-11-14 04:39:47 +0000
commitd02548c0925a02dd0af64a9dc13cce9e84d87b4f (patch)
tree0bdccf0887cdc1ff1b697d6b790df11cac7fb839 /staptree.h
parenta14d81b2a2cce703422e596fd2f3d6ea699e93ce (diff)
downloadsystemtap-steved-d02548c0925a02dd0af64a9dc13cce9e84d87b4f.tar.gz
systemtap-steved-d02548c0925a02dd0af64a9dc13cce9e84d87b4f.tar.xz
systemtap-steved-d02548c0925a02dd0af64a9dc13cce9e84d87b4f.zip
2005-11-13 Graydon Hoare <graydon@redhat.com>
* staptree.h (struct indexable): New struct. (classify_indexable): New function. (classify_const_indexable): New function. (struct symbol): Implement indexable. (struct arrayindex): Take indexable as base. (struct foreach_loop): Take indexable as base. (struct print_format): New struct. (enum stat_component_type): New enum. (struct stat_op): New struct. (enum historgram_type): New enum. (struct hist_op): New struct. (struct visitor) (struct traversing_visitor) (struct throwing_visitor) (struct deep_copy_visitor): Add new visitor methods. (require): Specialize for indexable*. * staptree.cxx (print_format::*) (stat_op::*) (hist_op::*) (indexable::*) (traversing_visitor::*) (throwing_visitor::*) (deep_copy_visitor::*) (classify_indexable) (classify_const_indexable): Implement (deep_copy_visitor::*): Update to use indexables. * parse.h (parser::parse_indexable): New method. (parser::parse_hist_op_or_bare_name): New method. * parse.cxx (lexer::scan): Accept @ in identifiers. (parser::parse_array_in) (parser::parse_foreach_loop): Call parse_indexable. (parser::parse_hist_op_or_bare_name): Implement. (parser::parse_indexable): Implement. (parser::parse_symbol): Accept printf, stat_ops, hist_ops. * elaborate.h (struct typeresolution_info): Add methods for visiting print_format, stat_op, hist_op. * elaborate.cxx (symbol_fetcher): New class. (get_symbol_within_expression): New function. (get_symbol_within_indexable): New function. (mutated_var_collector): Replace mutated_map_collector. (no_var_mutation_during_iteration_check): Replace no_map_mutation_during_iteration_check. (semantic_pass_vars): Replace semantic_pass_maps. (semantic_pass): Update call accordingly. (symresolution_info::*) Add new visitors, teach about indexables (typeresolution_info::*) Likewise. * translate.cxx (c_unparser::getiter): Take symbol, not foreach_loop. (c_unparser::*) Add new visitors, teach about indexables. (c_tmpcounter::*) (delete_statement_operand_visitor::visit_arrayindex) (c_tmpcounter_assignment::*) (c_unparser_assignment::*): Likewise. (hist_op_downcaster): New struct. (expression_is_hist_op): New function. * testsuite/buildok/printf.stp: New test for print_format.
Diffstat (limited to 'staptree.h')
-rw-r--r--staptree.h172
1 files changed, 167 insertions, 5 deletions
diff --git a/staptree.h b/staptree.h
index 11628b18..b509ad7a 100644
--- a/staptree.h
+++ b/staptree.h
@@ -172,15 +172,50 @@ struct assignment: public binary_expression
void visit (visitor* u);
};
+struct symbol;
+struct hist_op;
+struct indexable
+{
+ // This is a helper class which, type-wise, acts as a disjoint union
+ // of symbols and histograms. You can ask it whether it's a
+ // histogram or a symbol, and downcast accordingly.
+ void print_indexable (std::ostream& o) const;
+ void visit_indexable (visitor* u);
+ virtual bool is_symbol(symbol *& sym_out);
+ virtual bool is_hist_op(hist_op *& hist_out);
+ virtual bool is_const_symbol(const symbol *& sym_out) const;
+ virtual bool is_const_hist_op(const hist_op *& hist_out) const;
+ virtual const token *get_tok() const = 0;
+ virtual ~indexable() {}
+};
+
+// Perform a downcast to one out-value and NULL the other, throwing an
+// exception if neither downcast succeeds. This is (sadly) about the
+// best we can accomplish in C++.
+void
+classify_indexable(indexable* ix,
+ symbol *& array_out,
+ hist_op *& hist_out);
+
+void
+classify_const_indexable(const indexable* ix,
+ symbol const *& array_out,
+ hist_op const *& hist_out);
class vardecl;
-struct symbol: public expression
+struct symbol:
+ public expression,
+ public indexable
{
std::string name;
vardecl *referent;
symbol ();
void print (std::ostream& o) const;
void visit (visitor* u);
+ // overrides of type 'indexable'
+ const token *get_tok() const;
+ bool is_const_symbol(const symbol *& sym_out) const;
+ bool is_symbol(symbol *& sym_out);
};
@@ -200,9 +235,8 @@ struct target_symbol : public expression
struct arrayindex: public expression
{
- std::string base;
std::vector<expression*> indexes;
- vardecl *referent;
+ indexable *base;
arrayindex ();
void print (std::ostream& o) const;
void visit (visitor* u);
@@ -221,6 +255,97 @@ struct functioncall: public expression
};
+struct print_format: public expression
+{
+ bool print_with_format;
+ bool print_to_stream;
+
+ enum format_flag
+ {
+ fmt_flag_zeropad = 1,
+ fmt_flag_plus = 2,
+ fmt_flag_space = 4,
+ fmt_flag_left = 8,
+ fmt_flag_special = 16
+ };
+
+ enum conversion_type
+ {
+ conv_unspecified,
+ conv_signed_decimal,
+ conv_unsigned_decimal,
+ conv_unsigned_octal,
+ conv_unsigned_uppercase_hex,
+ conv_unsigned_lowercase_hex,
+ conv_string,
+ conv_literal
+ };
+
+ struct format_component
+ {
+ unsigned long flags;
+ unsigned width;
+ unsigned precision;
+ conversion_type type;
+ std::string literal_string;
+ void clear()
+ {
+ flags = 0;
+ width = 0;
+ precision = 0;
+ type = conv_unspecified;
+ literal_string.clear();
+ }
+ };
+
+ std::vector<format_component> components;
+ std::vector<expression*> args;
+
+ static std::string components_to_string(std::vector<format_component> const & components);
+ static std::vector<format_component> string_to_components(std::string const & str);
+
+ void print (std::ostream& o) const;
+ void visit (visitor* u);
+};
+
+
+enum stat_component_type
+ {
+ sc_average,
+ sc_count,
+ sc_sum,
+ sc_min,
+ sc_max,
+ };
+
+struct stat_op: public expression
+{
+ stat_component_type ctype;
+ expression* stat;
+ void print (std::ostream& o) const;
+ void visit (visitor* u);
+};
+
+enum histogram_type
+ {
+ hist_linear,
+ hist_log
+ };
+
+struct hist_op: public indexable
+{
+ const token* tok;
+ histogram_type htype;
+ expression* stat;
+ std::vector<int64_t> params;
+ void print (std::ostream& o) const;
+ void visit (visitor* u);
+ // overrides of type 'indexable'
+ const token *get_tok() const;
+ bool is_const_hist_op(const hist_op *& hist_out) const;
+ bool is_hist_op(hist_op *& hist_out);
+};
+
// ------------------------------------------------------------------------
@@ -316,8 +441,7 @@ struct foreach_loop: public statement
{
// this part is a specialization of arrayindex
std::vector<symbol*> indexes;
- std::string base;
- vardecl* base_referent;
+ indexable *base;
int sort_direction; // -1: decreasing, 0: none, 1: increasing
unsigned sort_column; // 0: value, 1..N: index
@@ -486,6 +610,9 @@ struct visitor
virtual void visit_target_symbol (target_symbol* e) = 0;
virtual void visit_arrayindex (arrayindex* e) = 0;
virtual void visit_functioncall (functioncall* e) = 0;
+ virtual void visit_print_format (print_format* e) = 0;
+ virtual void visit_stat_op (stat_op* e) = 0;
+ virtual void visit_hist_op (hist_op* e) = 0;
};
@@ -523,6 +650,9 @@ struct traversing_visitor: public visitor
void visit_target_symbol (target_symbol* e);
void visit_arrayindex (arrayindex* e);
void visit_functioncall (functioncall* e);
+ void visit_print_format (print_format* e);
+ void visit_stat_op (stat_op* e);
+ void visit_hist_op (hist_op* e);
};
@@ -565,6 +695,9 @@ struct throwing_visitor: public visitor
void visit_target_symbol (target_symbol* e);
void visit_arrayindex (arrayindex* e);
void visit_functioncall (functioncall* e);
+ void visit_print_format (print_format* e);
+ void visit_stat_op (stat_op* e);
+ void visit_hist_op (hist_op* e);
};
// A visitor which performs a deep copy of the root node it's applied
@@ -609,6 +742,9 @@ struct deep_copy_visitor: public visitor
virtual void visit_target_symbol (target_symbol* e);
virtual void visit_arrayindex (arrayindex* e);
virtual void visit_functioncall (functioncall* e);
+ virtual void visit_print_format (print_format* e);
+ virtual void visit_stat_op (stat_op* e);
+ virtual void visit_hist_op (hist_op* e);
};
template <typename T> static void
@@ -624,6 +760,32 @@ require (deep_copy_visitor* v, T* dst, T src)
}
}
+template <> static void
+require <indexable *> (deep_copy_visitor* v, indexable** dst, indexable* src)
+{
+ if (src != NULL)
+ {
+ symbol *array_src=NULL, *array_dst=NULL;
+ hist_op *hist_src=NULL, *hist_dst=NULL;
+
+ classify_indexable(src, array_src, hist_src);
+
+ *dst = NULL;
+
+ if (array_src)
+ {
+ require <symbol*> (v, &array_dst, array_src);
+ *dst = array_dst;
+ }
+ else
+ {
+ require <hist_op*> (v, &hist_dst, hist_src);
+ *dst = hist_dst;
+ }
+ assert (*dst);
+ }
+}
+
template <typename T> static void
provide (deep_copy_visitor* v, T src)
{