00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "c_breeze.h"
00040
00041
00042
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
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
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
00133
00134
00135 }
00136
00137
00138 void operandNode::eval() {
00139 value(constant());
00140 }
00141
00142
00143
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
00160
00161
00162
00163
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
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
00202
00203
00204
00205
00206
00207
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
00228
00229
00230 void operandNode::output_expr(output_context & ct, Node * parent, int prec,
00231 Assoc assoc)
00232 {
00233
00234
00235
00236
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
00274
00275
00276 void operandNode::dataflow(FlowVal * v, FlowProblem & fp)
00277 {
00278
00279 }