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  

operandnode.cc

Go to the documentation of this file.
00001 // $Id: operandnode.cc,v 1.6 2003/08/11 17:17:30 abrown 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 //  Adam Brown
00013 // 
00014 //  Permission is hereby granted, free of charge, to any person
00015 //  obtaining a copy of this software and associated documentation
00016 //  files (the "Software"), to deal in the Software without
00017 //  restriction, including without limitation the rights to use, copy,
00018 //  modify, merge, publish, distribute, sublicense, and/or sell copies
00019 //  of the Software, and to permit persons to whom the Software is
00020 //  furnished to do so, subject to the following conditions:
00021 //  
00022 //  The above copyright notice and this permission notice shall be
00023 //  included in all copies or substantial portions of the Software.
00024 //  
00025 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00026 //  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00027 //  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00028 //  NONINFRINGEMENT.  IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT
00029 //  AUSTIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00030 //  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
00031 //  OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00032 //  THE SOFTWARE.
00033 //
00034 //  We acknowledge the C-to-C Translator from MIT Laboratory for
00035 //  Computer Science for inspiring parts of the C-Breeze design.
00036 //
00037 // ----------------------------------------------------------------------
00038 
00039 #include "c_breeze.h"
00040 
00041 // --------------------------------------------------------------------
00042 // Constructors
00043 // --------------------------------------------------------------------
00044 
00045 operandNode::operandNode(indexNode * the_var, const Coord coord):
00046   exprNode(Operand, NULL, coord),
00047   _var(the_var),
00048   _star(false),
00049   _addr(false),
00050   _cast(NULL),
00051   _fields(),
00052   _index(NULL)
00053 {}
00054 
00055 operandNode::operandNode(indexNode * the_var, bool star, bool addr,
00056                          const Coord coord):
00057   exprNode(Operand, NULL, coord),
00058   _var(the_var),
00059   _star(star),
00060   _addr(addr),
00061   _cast(NULL),
00062   _fields(),
00063   _index(NULL)
00064 {}
00065 
00066 operandNode::operandNode(indexNode * the_var, bool star, bool addr, 
00067                          id_list * fields, indexNode * array_index, 
00068                          const Coord coord):
00069   exprNode(Operand, NULL, coord),
00070   _var(the_var),
00071   _star(star),
00072   _addr(addr),
00073   _cast(NULL),
00074   _fields(),
00075   _index(array_index)
00076 {
00077   if ( fields )
00078     _fields.swap(*fields);
00079 }
00080 
00081 typeNode * operandNode::type() const {
00082   // TODO: document & explain this
00083   if ( cast() )
00084     return (typeNode *) cast();
00085   return noncast_type();
00086 }
00087 
00088 typeNode * operandNode::noncast_type(bool convertArrays) const {
00089   typeNode * base_type = NULL;
00090   int deref = 0;
00091   if ( !fields().empty() )
00092     base_type = fields().back()->type();
00093   else if ( var()->typ() == Id ) {
00094     base_type = ((idNode *) var())->type();
00095     if(star()) deref++;
00096   } else if ( var()->typ() == Const ) {
00097     base_type = ((constNode *) var())->type();
00098     if(star()) deref++;
00099   }
00100   if ( index() ) deref++;
00101   if ( addr() ) deref--;
00102   if( base_type )
00103     base_type = base_type->follow_tdefs();
00104   if (deref < 0) {
00105     return new ptrNode(typeNode::NONE, base_type);
00106   } else {
00107     while(deref-- > 0) {
00108       typeNode * subtype;
00109       if ( base_type->typ() == Array )
00110         subtype = ((arrayNode *) base_type)->type();
00111       else if ( base_type->typ() == Ptr )
00112         subtype = ((ptrNode *) base_type)->type();
00113       else assert(false);
00114       if ( ( subtype->typ() == Array )
00115            && convertArrays )
00116         base_type= new ptrNode(typeNode::NONE, ((arrayNode*) subtype)->type());
00117       else
00118         base_type= subtype->follow_tdefs();
00119     }
00120     // incorrectly handled arrayNode for &(a[1]), should be ptrNode
00121     if ( arrayNode * arrayType = dynamic_cast<arrayNode *>(base_type) )
00122       if ( convertArrays )
00123         return new ptrNode(typeNode::NONE, arrayType->type());
00124       else
00125         return base_type;
00126     else
00127       return base_type;
00128   }
00129 }
00130 
00131 void operandNode::type(typeNode * type) {
00132   // do nothing, because an operandNode has no type of its own, just
00133   // the type of its most specific constituent
00134   // TODO: consider making this just call "cast(type);"
00135 }
00136 
00137 // TODO:  does this need to be anything else?
00138 void operandNode::eval() {
00139   value(constant());
00140 }
00141 
00142 // ------------------------------------------------------------
00143 //  Walker
00144 // ------------------------------------------------------------
00145 
00146 void operandNode::visit(Visitor * the_visitor) 
00147 {
00148   the_visitor->at_operand(this);
00149 }
00150 
00151 void operandNode::walk(Walker & the_walker)
00152 {
00153   Walker::Order ord = the_walker.order(); 
00154 
00155   if (ord == Walker::Preorder || ord == Walker::Both)
00156     the_walker.at_operand(this, Walker::Preorder);
00157 
00158   if (the_walker.depth() == Walker::Subtree) {
00159     // -- Visit the children 
00160     // don't want to do this b/c operandNode doesn't have a type of its
00161     // own (see doc on type()).  also makes the AST look non-tree
00162 //     if ( type() )
00163 //       type()->walk(the_walker);
00164 
00165     var()->walk(the_walker);
00166 
00167     list_walker(fields(), the_walker);
00168 
00169     if ( index() )
00170       index()->walk(the_walker);
00171   }
00172 
00173   if (ord == Walker::Postorder || ord == Walker::Both)
00174     the_walker.at_operand(this, Walker::Postorder);
00175 }
00176 
00177 // ------------------------------------------------------------
00178 //  Changer
00179 // ------------------------------------------------------------
00180 
00181 Node * operandNode::change(Changer & the_changer, bool redispatch)
00182 {
00183   Changer::Order ord = the_changer.order(); 
00184   operandNode * the_oper = this;
00185 
00186   if ((ord == Changer::Preorder || ord == Changer::Both) && ! redispatch)
00187     the_oper = (operandNode *) the_changer.at_operand(the_oper, 
00188                                                       Changer::Preorder);
00189 
00190   if (the_oper) {
00191     if (the_oper != this)
00192       return the_oper->change(the_changer, true);
00193 
00194     indexNode * old_var = the_oper->var();
00195     indexNode * new_var = (indexNode *) old_var->change(the_changer);
00196     if ( old_var != new_var )
00197       the_oper->var(new_var);
00198 
00199     change_list(the_oper->fields(), the_changer);
00200 
00201     // don't want to do this b/c operandNode doesn't have a type of its
00202     // own (see doc on type()).  also makes the AST look non-tree
00203 //     typeNode * old_type = the_oper->type();
00204 //     if (old_type) {
00205 //       typeNode * new_type = (typeNode *) old_type->change(the_changer);
00206 //       if (old_type != new_type) {
00207 //         the_oper->type(new_type);
00208 //       }
00209 //     }
00210 
00211     indexNode * old_index = the_oper->index();
00212     if ( old_index ) {
00213       indexNode * new_index = (indexNode *) old_index->change(the_changer);
00214       if ( old_index != new_index )
00215         the_oper->index(new_index);
00216     }
00217   }
00218 
00219   if ((ord == Changer::Postorder || ord == Changer::Both) && ! redispatch)
00220     the_oper = (operandNode *) the_changer.at_operand(the_oper, 
00221                                                       Changer::Postorder);
00222 
00223   return the_oper;
00224 }
00225 
00226 // ------------------------------------------------------------
00227 // Output
00228 // ------------------------------------------------------------
00229 
00230 void operandNode::output_expr(output_context & ct, Node * parent, int prec, 
00231                          Assoc assoc)
00232 {
00233   // precedence of operators: star, field, index, addr, cast
00234 
00235   // Not sure if we should do this, b/c the operandNode might be on the
00236   // right-hand side of an assignment => invalid C code.
00237   if ( cast() && parent && parent->typ()==ThreeAddr &&
00238        ((threeAddrNode*)parent)->lhs() != this ) {
00239     ct << '(';
00240     cast()->output(ct, this);
00241     ct << ')';
00242     ct.space();
00243   }
00244 
00245   if ( addr() ) {
00246     ct << '&';
00247     ct.space();
00248   }
00249 
00250   if ( star() ) {
00251     ct << '(';
00252     ct << '*';
00253   }
00254 
00255   var()->output(ct, this);
00256 
00257   if ( star() )
00258     ct << ')';
00259 
00260   for ( id_list_p p = fields().begin(); p != fields().end(); p++ ) {
00261     ct << '.';
00262     (*p)->output(ct, this);
00263   }
00264 
00265   if ( index() ) {
00266     ct << '[';
00267     index()->output(ct, this);
00268     ct << ']';
00269   }
00270 }
00271 
00272 // ------------------------------------------------------------
00273 //  Dataflow
00274 // ------------------------------------------------------------
00275 
00276 void operandNode::dataflow(FlowVal * v, FlowProblem & fp)
00277 {
00278   // TODO:  uhhh, sam?
00279 }

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