pt-check.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1996-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026 
00027 #include "error.h"
00028 #include "input.h"
00029 #include "ov-usr-fcn.h"
00030 #include "pt-all.h"
00031 
00032 void
00033 tree_checker::visit_argument_list (tree_argument_list& lst)
00034 {
00035   tree_argument_list::iterator p = lst.begin ();
00036 
00037   while (p != lst.end ())
00038     {
00039       tree_expression *elt = *p++;
00040 
00041       if (elt)
00042         {
00043           if (do_lvalue_check && ! elt->lvalue_ok ())
00044             gripe ("invalid lvalue in multiple assignment", elt->line ());
00045         }
00046     }
00047 }
00048 
00049 void
00050 tree_checker::visit_binary_expression (tree_binary_expression& expr)
00051 {
00052   tree_expression *op1 = expr.lhs ();
00053 
00054   if (op1)
00055     op1->accept (*this);
00056 
00057   tree_expression *op2 = expr.rhs ();
00058 
00059   if (op2)
00060     op2->accept (*this);
00061 }
00062 
00063 void
00064 tree_checker::visit_break_command (tree_break_command&)
00065 {
00066 }
00067 
00068 void
00069 tree_checker::visit_colon_expression (tree_colon_expression& expr)
00070 {
00071   tree_expression *op1 = expr.base ();
00072 
00073   if (op1)
00074     op1->accept (*this);
00075 
00076   tree_expression *op3 = expr.increment ();
00077 
00078   if (op3)
00079     op3->accept (*this);
00080 
00081   tree_expression *op2 = expr.limit ();
00082 
00083   if (op2)
00084     op2->accept (*this);
00085 }
00086 
00087 void
00088 tree_checker::visit_continue_command (tree_continue_command&)
00089 {
00090 }
00091 
00092 void
00093 tree_checker::do_decl_command (tree_decl_command& cmd)
00094 {
00095   tree_decl_init_list *init_list = cmd.initializer_list ();
00096 
00097   if (init_list)
00098     init_list->accept (*this);
00099 }
00100 
00101 void
00102 tree_checker::visit_global_command (tree_global_command& cmd)
00103 {
00104   do_decl_command (cmd);
00105 }
00106 
00107 void
00108 tree_checker::visit_static_command (tree_static_command& cmd)
00109 {
00110   do_decl_command (cmd);
00111 }
00112 
00113 void
00114 tree_checker::visit_decl_elt (tree_decl_elt& cmd)
00115 {
00116   tree_identifier *id = cmd.ident ();
00117 
00118   if (id)
00119     id->accept (*this);
00120 
00121   tree_expression *expr = cmd.expression ();
00122 
00123   if (expr)
00124     expr->accept (*this);
00125 }
00126 
00127 void
00128 tree_checker::visit_decl_init_list (tree_decl_init_list& lst)
00129 {
00130   tree_decl_init_list::iterator p = lst.begin ();
00131 
00132   while (p != lst.end ())
00133     {
00134       tree_decl_elt *elt = *p++;
00135 
00136       if (elt)
00137         elt->accept (*this);
00138     }
00139 }
00140 
00141 void
00142 tree_checker::visit_simple_for_command (tree_simple_for_command& cmd)
00143 {
00144   tree_expression *lhs = cmd.left_hand_side ();
00145 
00146   if (lhs)
00147     {
00148       if (! lhs->lvalue_ok ())
00149         gripe ("invalid lvalue in for command", cmd.line ());
00150     }
00151 
00152   tree_expression *expr = cmd.control_expr ();
00153 
00154   if (expr)
00155     expr->accept (*this);
00156 
00157   tree_expression *maxproc = cmd.maxproc_expr ();
00158 
00159   if (maxproc)
00160     maxproc->accept (*this);
00161 
00162   tree_statement_list *list = cmd.body ();
00163 
00164   if (list)
00165     list->accept (*this);
00166 }
00167 
00168 void
00169 tree_checker::visit_complex_for_command (tree_complex_for_command& cmd)
00170 {
00171   tree_argument_list *lhs = cmd.left_hand_side ();
00172 
00173   if (lhs)
00174     {
00175       int len = lhs->length ();
00176 
00177       if (len == 0 || len > 2)
00178         gripe ("invalid number of output arguments in for command",
00179                cmd.line ());
00180 
00181       do_lvalue_check = true;
00182 
00183       lhs->accept (*this);
00184 
00185       do_lvalue_check = false;
00186     }
00187 
00188   tree_expression *expr = cmd.control_expr ();
00189 
00190   if (expr)
00191     expr->accept (*this);
00192 
00193   tree_statement_list *list = cmd.body ();
00194 
00195   if (list)
00196     list->accept (*this);
00197 }
00198 
00199 void
00200 tree_checker::visit_octave_user_script (octave_user_script& fcn)
00201 {
00202   tree_statement_list *cmd_list = fcn.body ();
00203 
00204   if (cmd_list)
00205     cmd_list->accept (*this);
00206 }
00207 
00208 void
00209 tree_checker::visit_octave_user_function (octave_user_function& fcn)
00210 {
00211   tree_statement_list *cmd_list = fcn.body ();
00212 
00213   if (cmd_list)
00214     cmd_list->accept (*this);
00215 }
00216 
00217 void
00218 tree_checker::visit_function_def (tree_function_def& fdef)
00219 {
00220   octave_value fcn = fdef.function ();
00221 
00222   octave_function *f = fcn.function_value ();
00223 
00224   if (f)
00225     f->accept (*this);
00226 }
00227 
00228 void
00229 tree_checker::visit_identifier (tree_identifier& /* id */)
00230 {
00231 }
00232 
00233 void
00234 tree_checker::visit_if_clause (tree_if_clause& cmd)
00235 {
00236   tree_expression *expr = cmd.condition ();
00237 
00238   if (expr)
00239     expr->accept (*this);
00240 
00241   tree_statement_list *list = cmd.commands ();
00242 
00243   if (list)
00244     list->accept (*this);
00245 }
00246 
00247 void
00248 tree_checker::visit_if_command (tree_if_command& cmd)
00249 {
00250   tree_if_command_list *list = cmd.cmd_list ();
00251 
00252   if (list)
00253     list->accept (*this);
00254 }
00255 
00256 void
00257 tree_checker::visit_if_command_list (tree_if_command_list& lst)
00258 {
00259   tree_if_command_list::iterator p = lst.begin ();
00260 
00261   while (p != lst.end ())
00262     {
00263       tree_if_clause *elt = *p++;
00264 
00265       if (elt)
00266         elt->accept (*this);
00267     }
00268 }
00269 
00270 void
00271 tree_checker::visit_index_expression (tree_index_expression& expr)
00272 {
00273   tree_expression *e = expr.expression ();
00274 
00275   if (e)
00276     e->accept (*this);
00277 
00278   std::list<tree_argument_list *> lst = expr.arg_lists ();
00279 
00280   std::list<tree_argument_list *>::iterator p = lst.begin ();
00281 
00282   while (p != lst.end ())
00283     {
00284       tree_argument_list *elt = *p++;
00285 
00286       if (elt)
00287         elt->accept (*this);
00288     }
00289 }
00290 
00291 void
00292 tree_checker::visit_matrix (tree_matrix& lst)
00293 {
00294   tree_matrix::iterator p = lst.begin ();
00295 
00296   while (p != lst.end ())
00297     {
00298       tree_argument_list *elt = *p++;
00299 
00300       if (elt)
00301         elt->accept (*this);
00302     }
00303 }
00304 
00305 void
00306 tree_checker::visit_cell (tree_cell& lst)
00307 {
00308   tree_matrix::iterator p = lst.begin ();
00309 
00310   while (p != lst.end ())
00311     {
00312       tree_argument_list *elt = *p++;
00313 
00314       if (elt)
00315         elt->accept (*this);
00316     }
00317 }
00318 
00319 void
00320 tree_checker::visit_multi_assignment (tree_multi_assignment& expr)
00321 {
00322   tree_argument_list *lhs = expr.left_hand_side ();
00323 
00324   if (lhs)
00325     {
00326       do_lvalue_check = true;
00327 
00328       lhs->accept (*this);
00329 
00330       do_lvalue_check = false;
00331     }
00332 
00333   tree_expression *rhs = expr.right_hand_side ();
00334 
00335   if (rhs)
00336     rhs->accept (*this);
00337 }
00338 
00339 void
00340 tree_checker::visit_no_op_command (tree_no_op_command& /* cmd */)
00341 {
00342 }
00343 
00344 void
00345 tree_checker::visit_anon_fcn_handle (tree_anon_fcn_handle& /* afh */)
00346 {
00347 }
00348 
00349 void
00350 tree_checker::visit_constant (tree_constant& /* val */)
00351 {
00352 }
00353 
00354 void
00355 tree_checker::visit_fcn_handle (tree_fcn_handle& /* fh */)
00356 {
00357 }
00358 
00359 void
00360 tree_checker::visit_parameter_list (tree_parameter_list& lst)
00361 {
00362   tree_parameter_list::iterator p = lst.begin ();
00363 
00364   while (p != lst.end ())
00365     {
00366       tree_decl_elt *elt = *p++;
00367 
00368       if (elt)
00369         elt->accept (*this);
00370     }
00371 }
00372 
00373 void
00374 tree_checker::visit_postfix_expression (tree_postfix_expression& expr)
00375 {
00376   tree_expression *e = expr.operand ();
00377 
00378   if (e)
00379     e->accept (*this);
00380 }
00381 
00382 void
00383 tree_checker::visit_prefix_expression (tree_prefix_expression& expr)
00384 {
00385   tree_expression *e = expr.operand ();
00386 
00387   if (e)
00388     e->accept (*this);
00389 }
00390 
00391 void
00392 tree_checker::visit_return_command (tree_return_command&)
00393 {
00394 }
00395 
00396 void
00397 tree_checker::visit_return_list (tree_return_list& lst)
00398 {
00399   tree_return_list::iterator p = lst.begin ();
00400 
00401   while (p != lst.end ())
00402     {
00403       tree_index_expression *elt = *p++;
00404 
00405       if (elt)
00406         elt->accept (*this);
00407     }
00408 }
00409 
00410 void
00411 tree_checker::visit_simple_assignment (tree_simple_assignment& expr)
00412 {
00413   tree_expression *lhs = expr.left_hand_side ();
00414 
00415   if (lhs)
00416     {
00417       if (! lhs->lvalue_ok ())
00418         gripe ("invalid lvalue in assignment", expr.line ());
00419     }
00420 
00421   tree_expression *rhs = expr.right_hand_side ();
00422 
00423   if (rhs)
00424     rhs->accept (*this);
00425 }
00426 
00427 void
00428 tree_checker::visit_statement (tree_statement& stmt)
00429 {
00430   tree_command *cmd = stmt.command ();
00431 
00432   if (cmd)
00433     cmd->accept (*this);
00434   else
00435     {
00436       tree_expression *expr = stmt.expression ();
00437 
00438       if (expr)
00439         expr->accept (*this);
00440     }
00441 }
00442 
00443 void
00444 tree_checker::visit_statement_list (tree_statement_list& lst)
00445 {
00446   for (tree_statement_list::iterator p = lst.begin (); p != lst.end (); p++)
00447     {
00448       tree_statement *elt = *p;
00449 
00450       if (elt)
00451         elt->accept (*this);
00452     }
00453 }
00454 
00455 void
00456 tree_checker::visit_switch_case (tree_switch_case& cs)
00457 {
00458   tree_expression *label = cs.case_label ();
00459 
00460   if (label)
00461     label->accept (*this);
00462 
00463   tree_statement_list *list = cs.commands ();
00464 
00465   if (list)
00466     list->accept (*this);
00467 }
00468 
00469 void
00470 tree_checker::visit_switch_case_list (tree_switch_case_list& lst)
00471 {
00472   tree_switch_case_list::iterator p = lst.begin ();
00473 
00474   while (p != lst.end ())
00475     {
00476       tree_switch_case *elt = *p++;
00477 
00478       if (elt)
00479         elt->accept (*this);
00480     }
00481 }
00482 
00483 void
00484 tree_checker::visit_switch_command (tree_switch_command& cmd)
00485 {
00486   tree_expression *expr = cmd.switch_value ();
00487 
00488   if (expr)
00489     expr->accept (*this);
00490 
00491   tree_switch_case_list *list = cmd.case_list ();
00492 
00493   if (list)
00494     list->accept (*this);
00495 }
00496 
00497 void
00498 tree_checker::visit_try_catch_command (tree_try_catch_command& cmd)
00499 {
00500   tree_statement_list *try_code = cmd.body ();
00501 
00502   if (try_code)
00503     try_code->accept (*this);
00504 
00505   tree_statement_list *catch_code = cmd.cleanup ();
00506 
00507   if (catch_code)
00508     catch_code->accept (*this);
00509 }
00510 
00511 void
00512 tree_checker::visit_unwind_protect_command
00513   (tree_unwind_protect_command& cmd)
00514 {
00515   tree_statement_list *unwind_protect_code = cmd.body ();
00516 
00517   if (unwind_protect_code)
00518     unwind_protect_code->accept (*this);
00519 
00520   tree_statement_list *cleanup_code = cmd.cleanup ();
00521 
00522   if (cleanup_code)
00523     cleanup_code->accept (*this);
00524 }
00525 
00526 void
00527 tree_checker::visit_while_command (tree_while_command& cmd)
00528 {
00529   tree_expression *expr = cmd.condition ();
00530 
00531   if (expr)
00532     expr->accept (*this);
00533 
00534   tree_statement_list *list = cmd.body ();
00535 
00536   if (list)
00537     list->accept (*this);
00538 }
00539 
00540 void
00541 tree_checker::visit_do_until_command (tree_do_until_command& cmd)
00542 {
00543   tree_statement_list *list = cmd.body ();
00544 
00545   if (list)
00546     list->accept (*this);
00547 
00548   tree_expression *expr = cmd.condition ();
00549 
00550   if (expr)
00551     expr->accept (*this);
00552 }
00553 
00554 void
00555 tree_checker::gripe (const std::string& msg, int line)
00556 {
00557   if (curr_fcn_file_name.empty ())
00558     error ("%s", msg.c_str ());
00559   else
00560     error ("%s: %d: %s", curr_fcn_file_name.c_str (), line, msg.c_str ());
00561 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines