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  

arraynode.cc

Go to the documentation of this file.
00001 // $Id: arraynode.cc,v 1.5 2003/08/07 23:12:55 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 #include "semcheck.h"
00040 
00041 // --------------------------------------------------------------------
00042 // Constructors
00043 // --------------------------------------------------------------------
00044 
00045 arrayNode::arrayNode(Type_qualifiers tq, typeNode * the_type, exprNode * the_dim,
00046                    const Coord coord)
00047   : typeNode(Array, tq, the_type, coord),
00048     _dim(the_dim),
00049     _size(0) { }
00050 
00051 // ------------------------------------------------------------
00052 //  Data type predicates
00053 // ------------------------------------------------------------
00054 
00055 bool arrayNode::is_string() const
00056 {
00057   return type()->is_char();
00058 }
00059 
00060 // ------------------------------------------------------------
00061 //  Type Equal
00062 // ------------------------------------------------------------
00063 
00064 bool arrayNode::qualified_equal_to(typeNode * node2,
00065                                   bool strict_toplevel, bool strict_recursive)
00066 {
00067   // pnav
00068   // this comparison of types should work for array-array and array-ptr comparisons
00069   if (! equal_to(type(), node2->type(),
00070                  strict_recursive, strict_recursive))
00071     return false;
00072 
00073   // pnav
00074   // if node2 is a ptrNode, and the base types are equal (checked above) 
00075   // then return true
00076   if (node2->typ() == Ptr)
00077     return true;
00078 
00079   // Either both dims are specified and the same or neither is...
00080   arrayNode * n2 = (arrayNode *) node2;
00081   if (dim())
00082     if (n2->dim()) {
00083 /* djimenez replaced this:
00084       exprNode * dim1 = get_dim();
00085       exprNode * dim2 = n2->get_dim();
00086    with this:
00087 */
00088       exprNode * dim1 = dim();
00089       exprNode * dim2 = n2->dim();
00090 /* because it was causing array second dimensions to be squished
00091    when they were in the same parameter of two prototypes being
00092    compared.
00093 */
00094 
00095       semcheck_expr_visitor::check(dim1);
00096       dim1->eval();
00097 
00098       semcheck_expr_visitor::check(dim2);
00099       dim2->eval();
00100 
00101       if ( ! dim1->value().no_val() &&
00102            ! dim2->value().no_val() ) {
00103 
00104         unsigned long val1 = dim1->value().Integer();
00105         unsigned long val2 = dim2->value().Integer();
00106 
00107         // -- Get the actual dimensions..must be non-zero and equal
00108 
00109         if (val1 && val2)
00110           return val1 == val2;
00111         else
00112           return false;
00113      
00114       } else
00115         return true; // -- TBD: What if constants have not been computed yet?
00116 
00117     } else
00118       // return false; // pnav
00119       // OpenGL code, while poor style, has arrays where one dimension is not specified
00120       return true;
00121 
00122   else {
00123     // -- Set the dimension and type...
00124     dim(n2->dim());
00125     type(n2->type());
00126   }
00127 
00128   return true;
00129 }
00130 
00131 // ------------------------------------------------------------
00132 //  Walker
00133 // ------------------------------------------------------------
00134 
00135 void arrayNode::visit(Visitor * the_visitor) 
00136 {
00137   the_visitor->at_array(this);
00138 }
00139 
00140 void arrayNode::walk(Walker & the_walker)
00141 {
00142   Walker::Order ord = the_walker.order(); 
00143 
00144   if (ord == Walker::Preorder || ord == Walker::Both)
00145     the_walker.at_array(this, Walker::Preorder);
00146 
00147   if (the_walker.depth() == Walker::Subtree) {
00148     // -- Visit the children 
00149 
00150     if (type())
00151       type()->walk(the_walker);
00152 
00153     if (dim())
00154       dim()->walk(the_walker);
00155   }
00156 
00157   if (ord == Walker::Postorder || ord == Walker::Both)
00158     the_walker.at_array(this, Walker::Postorder);
00159 }
00160 
00161 // ------------------------------------------------------------
00162 // Output
00163 // ------------------------------------------------------------
00164 
00165 void arrayNode::output_type(output_context & ct, Node * parent, Assoc context, Type_qualifiers q)
00166 {
00167   if (context == Left)
00168     type()->output_type(ct, this, Left, q);
00169   else {
00170     ct << '[';
00171     // djimenez
00172     // dim() is null sometimes, like when initializing an array e.g.
00173     // int foo[] = { 1, 2, 3 };
00174 
00175     if (dim()) dim()->output(ct, this);
00176     ct << ']';
00177 
00178     type()->output_type(ct, this, Right, q);
00179   }
00180 }
00181 
00182 // ------------------------------------------------------------
00183 //  Changer
00184 // ------------------------------------------------------------
00185 
00186 Node * arrayNode::change(Changer & the_changer, bool redispatch)
00187 {
00188   Changer::Order ord = the_changer.order(); 
00189   arrayNode * the_array = this;
00190 
00191   if ((ord == Changer::Preorder || ord == Changer::Both) && ! redispatch)
00192     the_array = (arrayNode *) the_changer.at_array(the_array, Changer::Preorder);
00193 
00194   if (the_array) {
00195 
00196     if (the_array != this)
00197       return the_array->change(the_changer, true);
00198 
00199     typeNode * old_type = the_array->type();
00200     if (old_type) {
00201       typeNode * new_type = (typeNode *) old_type->change(the_changer);
00202       if (old_type != new_type) {
00203         //if (the_changer.delete_old())
00204           //delete old_type;
00205         the_array->type(new_type);
00206       }
00207     }
00208 
00209     exprNode * old_dim = the_array->dim();
00210     if (old_dim) {
00211       exprNode * new_dim = (exprNode *) old_dim->change(the_changer);
00212       if (old_dim != new_dim) {
00213         //if (the_changer.delete_old())
00214          // delete old_dim;
00215         the_array->dim(new_dim);
00216       }
00217     }
00218 
00219   }
00220 
00221   if ((ord == Changer::Postorder || ord == Changer::Both) && ! redispatch)
00222     the_array = (arrayNode *) the_changer.at_array(the_array, Changer::Postorder);
00223 
00224   return the_array;
00225 }
00226 
00227 
00228 // ------------------------------------------------------------
00229 // Destructor
00230 // ------------------------------------------------------------
00231 
00232 arrayNode::~arrayNode()
00233 {
00234   //delete _dim;
00235 }

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