diff options
author | brolley <brolley> | 2008-02-27 16:42:35 +0000 |
---|---|---|
committer | brolley <brolley> | 2008-02-27 16:42:35 +0000 |
commit | 34201621cc07339371c8d74ce0fe609d967771d4 (patch) | |
tree | f2122e04569f569d2ff848435af6c2f343a2ac63 /elaborate.cxx | |
parent | 67bae0e3d979d554acaeb2a09cf4f7463ee713da (diff) | |
download | systemtap-steved-34201621cc07339371c8d74ce0fe609d967771d4.tar.gz systemtap-steved-34201621cc07339371c8d74ce0fe609d967771d4.tar.xz systemtap-steved-34201621cc07339371c8d74ce0fe609d967771d4.zip |
2008-02-21 Dave Brolley <brolley@redhat.com>
PR5189
* staptree.h (print_format::conv_memory): New enumerator.
(print_format::width_type): New enumeration.
(print_format::precision_type): New enumeration.
(format_component::widthtype): New member.
(format_component::prectype): New member.
(format_component::is_empty): Test widthtype and prectype.
(format_component::clear): Clear widthtype and prectype.
* staptree.cxx (print_format::components_to_string): Handle dynamic width and precision.
Handle conv_memory.
(print_format::string_to_components): Parse dynamic width and precision specifiers.
Set widthtype and prectype. Parse %m format specifier.
* elaborate.h (typeresolution_info::check_arg_type): New method.
* elaborate.cxx (typeresolution_info::visit_print_format): Account for dynamic width
and precision when computing the expected number of arguments. Check the types of
arguments for dynamic width and precision. Use check_arg_type to check the types of
all arguments. Handle print_format::conv_memory.
(typeresolution_info::check_arg_type): New method.
* NEWS: Describe the enhancements above.
Diffstat (limited to 'elaborate.cxx')
-rw-r--r-- | elaborate.cxx | 57 |
1 files changed, 43 insertions, 14 deletions
diff --git a/elaborate.cxx b/elaborate.cxx index bc0d1489..7f4ccf35 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -2854,6 +2854,7 @@ typeresolution_info::visit_print_format (print_format* e) // First we extract the subsequence of formatting components // which are conversions (not just literal string components) + unsigned expected_num_args = 0; std::vector<print_format::format_component> components; for (size_t i = 0; i < e->components.size(); ++i) { @@ -2864,19 +2865,39 @@ typeresolution_info::visit_print_format (print_format* e) || e->components[i].type == print_format::conv_size) continue; components.push_back(e->components[i]); + ++expected_num_args; + if (e->components[i].widthtype == print_format::width_dynamic) + ++expected_num_args; + if (e->components[i].prectype == print_format::prec_dynamic) + ++expected_num_args; } // Then we check that the number of conversions and the number // of args agree. - if (components.size() != e->args.size()) + if (expected_num_args != e->args.size()) throw semantic_error ("Wrong number of args to formatted print operator", e->tok); // Then we check that the types of the conversions match the types // of the args. + unsigned argno = 0; for (size_t i = 0; i < components.size(); ++i) { + // Check the dynamic width, if specified + if (components[i].widthtype == print_format::width_dynamic) + { + check_arg_type (pe_long, e->args[argno]); + ++argno; + } + + // Check the dynamic precision, if specified + if (components[i].prectype == print_format::prec_dynamic) + { + check_arg_type (pe_long, e->args[argno]); + ++argno; + } + exp_type wanted = pe_unknown; switch (components[i].type) @@ -2898,24 +2919,14 @@ typeresolution_info::visit_print_format (print_format* e) break; case print_format::conv_string: + case print_format::conv_memory: wanted = pe_string; break; } assert (wanted != pe_unknown); - - t = wanted; - e->args[i]->visit (this); - - if (e->args[i]->type == pe_unknown) - { - e->args[i]->type = wanted; - resolved (e->args[i]->tok, wanted); - } - else if (e->args[i]->type != wanted) - { - mismatch (e->args[i]->tok, e->args[i]->type, wanted); - } + check_arg_type (wanted, e->args[argno]); + ++argno; } } else @@ -2976,6 +2987,24 @@ typeresolution_info::visit_hist_op (hist_op* e) void +typeresolution_info::check_arg_type (exp_type wanted, expression* arg) +{ + t = wanted; + arg->visit (this); + + if (arg->type == pe_unknown) + { + arg->type = wanted; + resolved (arg->tok, wanted); + } + else if (arg->type != wanted) + { + mismatch (arg->tok, arg->type, wanted); + } +} + + +void typeresolution_info::unresolved (const token* tok) { num_still_unresolved ++; |