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  

castnode.cc

Go to the documentation of this file.
00001 // $Id: castnode.cc,v 1.4 2003/08/07 23:13:01 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 castNode::castNode(typeNode * type, exprNode * expr, bool implicit,
00045                    const Coord coord)
00046   : exprNode(Cast, type, coord),
00047     _expr(expr),
00048     _implicit(implicit)
00049 {}
00050 
00051 // ------------------------------------------------------------
00052 // Operator precedence
00053 // ------------------------------------------------------------
00054 
00055 int castNode::precedence(Assoc & assoc)
00056 {
00057   assoc = Right;
00058   return 14;
00059 }
00060 
00061 // ------------------------------------------------------------
00062 // Expression evaluator
00063 // ------------------------------------------------------------
00064 
00065 void castNode::eval()
00066 {
00067   // -- Evaluate the sub-expression
00068 
00069   expr()->eval();
00070 
00071   // -- The cast type must be primitive
00072 
00073   if (type()->typ() == Prim) {
00074 
00075     // -- Get the target basic type
00076 
00077     primNode * p = (primNode *) type();
00078     const basic_type & bt = p->basic();
00079 
00080     // -- Evaluate the cast
00081 
00082     value(constant::cast(bt, expr()->value()));
00083   }
00084   else
00085     value(constant());
00086 }
00087 
00088 // ------------------------------------------------------------
00089 //  Walker
00090 // ------------------------------------------------------------
00091 
00092 void castNode::visit(Visitor * the_visitor) 
00093 {
00094   the_visitor->at_cast(this);
00095 }
00096 
00097 void castNode::walk(Walker & the_walker)
00098 {
00099   Walker::Order ord = the_walker.order(); 
00100 
00101   if (ord == Walker::Preorder || ord == Walker::Both)
00102     the_walker.at_cast(this, Walker::Preorder);
00103 
00104   if (the_walker.depth() == Walker::Subtree) {
00105     // -- Visit the children 
00106 
00107     if (type())
00108       type()->walk(the_walker);
00109 
00110     if (expr())
00111       expr()->walk(the_walker);
00112   }
00113 
00114   if (ord == Walker::Postorder || ord == Walker::Both)
00115     the_walker.at_cast(this, Walker::Postorder);
00116 }
00117 
00118 // ------------------------------------------------------------
00119 //  Dataflow
00120 // ------------------------------------------------------------
00121 
00122 void castNode::dataflow(FlowVal * v, FlowProblem & fp)
00123 {
00124   if (fp.forward()) {
00125     fp.flow_cast(v, this, FlowProblem::Entry);
00126 
00127     if (expr())
00128       expr()->dataflow(v, fp);
00129 
00130     fp.flow_cast(v, this, FlowProblem::Exit);
00131   }
00132   else {
00133     fp.flow_cast(v, this, FlowProblem::Exit);
00134 
00135     if (expr())
00136       expr()->dataflow(v, fp);
00137 
00138     fp.flow_cast(v, this, FlowProblem::Entry);
00139   }
00140 }
00141 
00142 // ------------------------------------------------------------
00143 // Output
00144 // ------------------------------------------------------------
00145 
00146 void castNode::output_expr(output_context & ct, Node * parent, int prec, Assoc assoc)
00147 {
00148   // For implicit casts, just pass through
00149   if (is_implicit())
00150     expr()->output_expr(ct, this, prec, assoc);
00151   else {
00152 
00153     bool par = parens(prec, assoc);
00154     int myprec;
00155     Assoc myassoc;
00156 
00157     myprec = precedence(myassoc);
00158 
00159     if (par)
00160       ct << '(';
00161 
00162     ct << '(';
00163     type()->output(ct, this);
00164     ct << ')';
00165     ct.space();
00166     expr()->output_expr(ct, this, myprec, Right);
00167     
00168     if (par)
00169       ct << ')';
00170   }
00171 }
00172 
00173 // ------------------------------------------------------------
00174 //  Changer
00175 // ------------------------------------------------------------
00176 
00177 Node * castNode::change(Changer & the_changer, bool redispatch)
00178 {
00179   Changer::Order ord = the_changer.order(); 
00180   castNode * the_cast = this;
00181 
00182   if ((ord == Changer::Preorder || ord == Changer::Both) && ! redispatch)
00183     the_cast = (castNode *) the_changer.at_cast(the_cast, Changer::Preorder);
00184 
00185   if (the_cast) {
00186 
00187     if (the_cast != this)
00188       return the_cast->change(the_changer, true);
00189 
00190     typeNode * old_type = the_cast->type();
00191     if (old_type) {
00192       typeNode * new_type = (typeNode *) old_type->change(the_changer);
00193       if (old_type != new_type) {
00194         //if (the_changer.delete_old())
00195          // delete old_type;
00196         the_cast->type(new_type);
00197       }
00198     }
00199 
00200     exprNode * old_expr = the_cast->expr();
00201     if (old_expr) {
00202       exprNode * new_expr = (exprNode *) old_expr->change(the_changer);
00203       if (old_expr != new_expr) {
00204         //if (the_changer.delete_old())
00205          // delete old_expr;
00206         the_cast->expr(new_expr);
00207       }
00208     }
00209 
00210   }
00211 
00212   if ((ord == Changer::Postorder || ord == Changer::Both) && ! redispatch)
00213     the_cast = (castNode *) the_changer.at_cast(the_cast, Changer::Postorder);
00214 
00215   return the_cast;
00216 }
00217 
00218 
00219 // ------------------------------------------------------------
00220 // Destructor
00221 // ------------------------------------------------------------
00222 
00223 castNode::~castNode()
00224 {
00225   //delete _expr;
00226 }

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