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  

casenode.cc

Go to the documentation of this file.
00001 // $Id: casenode.cc,v 1.5 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 caseNode::caseNode(exprNode * expr, stmtNode * stmt, 
00045                    switchNode * the_container, const Coord coord)
00046   : targetNode(Case, stmt, coord),
00047     _expr(expr),
00048     _container(NULL)
00049 {
00050   container(the_container);
00051 }
00052 
00053 caseNode::caseNode(exprNode * expr, stmtNode * stmt,
00054                    const Coord the_coord)
00055   : targetNode(Case, stmt, the_coord),
00056     _expr(expr),
00057     _container(NULL)
00058 {}
00059 
00060 void caseNode::container(switchNode * container) {
00061   switchNode * old_container = _container;
00062   _container = container;
00063   if ( old_container )
00064     old_container->cases().remove(this);
00065   if ( container ) {
00066     container->cases().push_back(this);
00067     // TODO: should we do this?
00068     container->cases().sort();
00069     container->cases().unique();
00070   }
00071 }
00072 
00073 // ------------------------------------------------------------
00074 //  Walker
00075 // ------------------------------------------------------------
00076 
00077 void caseNode::visit(Visitor * the_visitor) 
00078 {
00079   the_visitor->at_case(this);
00080 }
00081 
00082 void caseNode::walk(Walker & the_walker)
00083 {
00084   Walker::Order ord = the_walker.order(); 
00085 
00086   if (ord == Walker::Preorder || ord == Walker::Both)
00087     the_walker.at_case(this, Walker::Preorder);
00088 
00089   if (the_walker.depth() == Walker::Subtree) {
00090     // -- Visit the children 
00091 
00092     if (expr())
00093       expr()->walk(the_walker);
00094 
00095     if (stmt())
00096       stmt()->walk(the_walker);
00097   }
00098 
00099   if (ord == Walker::Postorder || ord == Walker::Both)
00100     the_walker.at_case(this, Walker::Postorder);
00101 }
00102 
00103 // ------------------------------------------------------------
00104 //  Dataflow
00105 // ------------------------------------------------------------
00106 
00107 void caseNode::dataflow(FlowVal * v, FlowProblem & fp)
00108 {
00109   if (fp.forward()) {
00110 
00111     // -- Merge in values from the top of the switch
00112 
00113     if (container())
00114       v->meet(container()->at_top());
00115 
00116     fp.flow_case(v, this, FlowProblem::Entry);
00117 
00118     if (expr())
00119       if (fp.basicblocks()) {
00120         fp.flow_basicblock(v, expr(), FlowProblem::Entry);
00121         fp.flow_basicblock(v, expr(), FlowProblem::Exit);
00122       }
00123       else
00124         expr()->dataflow(v, fp);
00125 
00126     if (stmt())
00127       stmt()->dataflow(v, fp);
00128 
00129     fp.flow_case(v, this, FlowProblem::Exit);
00130   }
00131   else {
00132       fp.flow_case(v, this, FlowProblem::Exit);
00133 
00134       if (stmt())
00135         stmt()->dataflow(v, fp);
00136 
00137       if (expr())
00138         if (fp.basicblocks()) {
00139           fp.flow_basicblock(v, expr(), FlowProblem::Exit);
00140           fp.flow_basicblock(v, expr(), FlowProblem::Entry);
00141         }
00142         else
00143           expr()->dataflow(v, fp);
00144 
00145       fp.flow_case(v, this, FlowProblem::Entry);
00146 
00147       // -- Send values to the top of the switch
00148 
00149       if (container())
00150         v->meet(container()->at_top());
00151   }
00152 }
00153 
00154 // ------------------------------------------------------------
00155 // Output
00156 // ------------------------------------------------------------
00157 
00158 void caseNode::output_stmt(output_context & ct, Node * parent)
00159 {
00160 
00161   if (expr()) {
00162     ct << "case ";
00163     expr()->output(ct, this);
00164   }
00165   else
00166     ct << "default";
00167 
00168   ct << ':';
00169 
00170     if (stmt())
00171       stmt()->output(ct, this);
00172   else
00173     ct << ';';
00174 }
00175 
00176 // ------------------------------------------------------------
00177 //  Changer
00178 // ------------------------------------------------------------
00179 
00180 Node * caseNode::change(Changer & the_changer, bool redispatch)
00181 {
00182   Changer::Order ord = the_changer.order(); 
00183   caseNode * the_case = this;
00184 
00185   if ((ord == Changer::Preorder || ord == Changer::Both) && ! redispatch)
00186     the_case = (caseNode *) the_changer.at_case(the_case, Changer::Preorder);
00187 
00188   if (the_case) {
00189 
00190     if (the_case != this)
00191       return the_case->change(the_changer, true);
00192 
00193     exprNode * old_expr = the_case->expr();
00194     if (old_expr) {
00195       exprNode * new_expr = (exprNode *) old_expr->change(the_changer);
00196       if (old_expr != new_expr) {
00197         //if (the_changer.delete_old())
00198          // delete old_expr;
00199         the_case->expr(new_expr);
00200       }
00201     }
00202 
00203     blockNode * old_stmt = the_case->stmt();
00204     if (old_stmt) {
00205       blockNode * new_stmt = (blockNode *) old_stmt->change(the_changer);
00206       if (old_stmt != new_stmt) {
00207         //if (the_changer.delete_old())
00208          // delete old_stmt;
00209         the_case->stmt(new_stmt);
00210       }
00211     }
00212 
00213   }
00214 
00215   if ((ord == Changer::Postorder || ord == Changer::Both) && ! redispatch)
00216     the_case = (caseNode *) the_changer.at_case(the_case, Changer::Postorder);
00217 
00218   return the_case;
00219 }
00220 
00221 
00222 // ------------------------------------------------------------
00223 // Destructor
00224 // ------------------------------------------------------------
00225 
00226 caseNode::~caseNode()
00227 {
00228   //delete _expr;
00229 }

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