C-Breeze
C Compiler Infrastructure

[ Project home page]
Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

unarynode.cc

Go to the documentation of this file.
00001 // $Id: unarynode.cc,v 1.5 2003/08/07 23:13:15 pnav Exp $
00002 // ----------------------------------------------------------------------
00003 //
00004 //  C-Breeze
00005 //  C Compiler Framework
00006 // 
00007 //  Copyright (c) 2000 University of Texas at Austin
00008 // 
00009 //  Samuel Z. Guyer
00010 //  Daniel A. Jimenez
00011 //  Calvin Lin
00012 // 
00013 //  Permission is hereby granted, free of charge, to any person
00014 //  obtaining a copy of this software and associated documentation
00015 //  files (the "Software"), to deal in the Software without
00016 //  restriction, including without limitation the rights to use, copy,
00017 //  modify, merge, publish, distribute, sublicense, and/or sell copies
00018 //  of the Software, and to permit persons to whom the Software is
00019 //  furnished to do so, subject to the following conditions:
00020 //  
00021 //  The above copyright notice and this permission notice shall be
00022 //  included in all copies or substantial portions of the Software.
00023 //  
00024 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00025 //  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00026 //  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00027 //  NONINFRINGEMENT.  IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT
00028 //  AUSTIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00029 //  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
00030 //  OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00031 //  THE SOFTWARE.
00032 //
00033 //  We acknowledge the C-to-C Translator from MIT Laboratory for
00034 //  Computer Science for inspiring parts of the C-Breeze design.
00035 //
00036 // ----------------------------------------------------------------------
00037 
00038 #include "c_breeze.h"
00039 
00040 // --------------------------------------------------------------------
00041 // Constructors
00042 // --------------------------------------------------------------------
00043 
00044 unaryNode::unaryNode(unsigned int op_id, exprNode * expr, const Coord coord)
00045   : exprNode(Unary, 0, coord),
00046     _op(0),
00047     _expr(expr),
00048     _sizeof_type(0)
00049 {
00050   switch (op_id) {
00051   case '*':
00052     _op = Operators::table[Operator::INDIR];
00053     break;
00054   case '&':
00055     _op = Operators::table[Operator::ADDRESS];
00056     break;
00057   case '-':
00058     _op = Operators::table[Operator::UMINUS];
00059     break;
00060   case '+':
00061     _op = Operators::table[Operator::UPLUS];
00062     break;
00063   default:
00064     _op = Operators::table[op_id];
00065     break;
00066   }
00067 }
00068 
00069 //    Special constructor for sizeof operator
00070 
00071 unaryNode::unaryNode(unsigned int op_id, typeNode * the_type, const Coord coord)
00072   : exprNode(Unary, 0, coord),
00073     _op(Operators::table[op_id]),
00074     _expr(0),
00075     _sizeof_type(the_type)
00076 {}
00077 
00078 // ------------------------------------------------------------
00079 // Symbol lookup
00080 // ------------------------------------------------------------
00081 
00082 /*
00083 void unaryNode::lookup()
00084 {
00085   if (op()->id() == Operator::POSTINC  ||  op()->id() == Operator::POSTDEC)
00086     expr()->lookup();
00087 }
00088 */
00089 
00090 // ------------------------------------------------------------
00091 // Expression evaluator
00092 // ------------------------------------------------------------
00093 
00094 void unaryNode::eval()
00095 {
00096   // Look out for sizeof
00097 
00098   if (expr()) {
00099 
00100     // -- Evaluate the argument
00101 
00102     expr()->eval();
00103 
00104     // -- Evaluate the operator
00105 
00106     value(constant::eval(op(),
00107                          expr()->value()));
00108   }
00109   else
00110     value(constant());
00111 }
00112 
00113 // ------------------------------------------------------------
00114 // Operator precedence
00115 // ------------------------------------------------------------
00116 
00117 int unaryNode::precedence(Assoc & assoc)
00118 {
00119   if (op()->is_left_assoc())
00120     assoc = Left;
00121   else
00122     assoc = Right;
00123 
00124   return op()->unary_prec();
00125 }
00126 
00127 // ------------------------------------------------------------
00128 //  Walker
00129 // ------------------------------------------------------------
00130 
00131 void unaryNode::visit(Visitor * the_visitor) 
00132 {
00133   the_visitor->at_unary(this);
00134 }
00135 
00136 void unaryNode::walk(Walker & the_walker)
00137 {
00138   Walker::Order ord = the_walker.order(); 
00139 
00140   if (ord == Walker::Preorder || ord == Walker::Both)
00141     the_walker.at_unary(this, Walker::Preorder);
00142 
00143   if (the_walker.depth() == Walker::Subtree) {
00144     // -- Visit the children 
00145 
00146     if (expr())
00147       expr()->walk(the_walker);
00148 
00149     if (type())
00150       type()->walk(the_walker);
00151 
00152     if (sizeof_type())
00153       sizeof_type()->walk(the_walker);
00154   }
00155 
00156   if (ord == Walker::Postorder || ord == Walker::Both)
00157     the_walker.at_unary(this, Walker::Postorder);
00158 }
00159 
00160 // ------------------------------------------------------------
00161 //  Dataflow
00162 // ------------------------------------------------------------
00163 
00164 void unaryNode::dataflow(FlowVal * v, FlowProblem & fp)
00165 {
00166   if (fp.forward()) {
00167     fp.flow_unary(v, this, FlowProblem::Entry);
00168 
00169     // -- sizeof operation is not executable...
00170 
00171     if (expr() && (op()->id() != Operator::SIZEOF))
00172       expr()->dataflow(v, fp);
00173 
00174     fp.flow_unary(v, this, FlowProblem::Exit);
00175   }
00176   else {
00177     fp.flow_unary(v, this, FlowProblem::Exit);
00178 
00179     if (expr() && (op()->id() != Operator::SIZEOF))
00180       expr()->dataflow(v, fp);
00181 
00182     fp.flow_unary(v, this, FlowProblem::Entry);
00183   }
00184 }
00185 
00186 // ------------------------------------------------------------
00187 // Output
00188 // ------------------------------------------------------------
00189 
00190 void unaryNode::output_expr(output_context & ct, Node * parent, int prec, Assoc assoc)
00191 {
00192   bool par = parens(prec, assoc);
00193 
00194   if (par)
00195     ct << '(';
00196 
00197   switch (op()->id()) {
00198   case Operator::SIZEOF:
00199 
00200     // djimenez - added the space after sizeof so things like
00201     // sizeof foo wouldn't show up as sizeoffoo
00202 
00203     ct << "sizeof ";
00204 
00205     if (sizeof_type()) {
00206       ct  << '(';
00207       sizeof_type()->output(ct, this);
00208       ct << ')';
00209     }
00210     else
00211       expr()->output_expr(ct, this, op()->unary_prec(), Right);
00212 
00213     break;
00214 
00215   case Operator::PREINC:
00216   case Operator::PREDEC:
00217 
00218     ct << op()->print();
00219     ct.space();
00220     expr()->output_expr(ct, this, op()->unary_prec(), Right);
00221 
00222     break;
00223 
00224   case Operator::POSTINC:
00225   case Operator::POSTDEC:
00226 
00227     expr()->output_expr(ct, this, op()->unary_prec(), Left);
00228     ct << op()->print();
00229 
00230     break;
00231 
00232   default:
00233 
00234     ct << op()->print();
00235     ct.space();
00236     expr()->output_expr(ct, this, op()->unary_prec(), Right);
00237 
00238     break;
00239   }
00240 
00241   if (par)
00242     ct << ')';
00243 }
00244 
00245 // ------------------------------------------------------------
00246 //  Changer
00247 // ------------------------------------------------------------
00248 
00249 Node * unaryNode::change(Changer & the_changer, bool redispatch)
00250 {
00251   Changer::Order ord = the_changer.order(); 
00252   unaryNode * the_unary = this;
00253 
00254   if ((ord == Changer::Preorder || ord == Changer::Both) && ! redispatch)
00255     the_unary = (unaryNode *) the_changer.at_unary(the_unary, Changer::Preorder);
00256 
00257   if (the_unary) {
00258 
00259     if (the_unary != this)
00260       return the_unary->change(the_changer, true);
00261 
00262     exprNode * old_expr = the_unary->expr();
00263     if (old_expr) {
00264       exprNode * new_expr = (exprNode *) old_expr->change(the_changer);
00265       if (old_expr != new_expr) {
00266         //if (the_changer.delete_old())
00267           //delete old_expr;
00268         the_unary->expr(new_expr);
00269       }
00270     }
00271 
00272     typeNode * old_type = the_unary->type();
00273     if (old_type) {
00274       typeNode * new_type = (typeNode *) old_type->change(the_changer);
00275       if (old_type != new_type) {
00276         //if (the_changer.delete_old())
00277           //delete old_type;
00278         the_unary->type(new_type);
00279       }
00280     }
00281 
00282     typeNode * old_sizeof_type = the_unary->sizeof_type();
00283     if (old_sizeof_type) {
00284       typeNode * new_sizeof_type = (typeNode *) old_sizeof_type->change(the_changer);
00285       if (old_sizeof_type != new_sizeof_type) {
00286         //if (the_changer.delete_old())
00287           //delete old_sizeof_type;
00288         the_unary->sizeof_type(new_sizeof_type);
00289       }
00290     }
00291 
00292   }
00293 
00294   if ((ord == Changer::Postorder || ord == Changer::Both) && ! redispatch)
00295     the_unary = (unaryNode *) the_changer.at_unary(the_unary, Changer::Postorder);
00296 
00297   return the_unary;
00298 }
00299 
00300 
00301 // ------------------------------------------------------------
00302 // Destructor
00303 // ------------------------------------------------------------
00304 
00305 unaryNode::~unaryNode()
00306 {
00307   //delete _expr;
00308 }

Generated on August 27, 2003
Back to the C-Breeze home page