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
00040
00041
00042 #include "c_breeze.h"
00043 #include "dismantle.h"
00044 #include "ref_clone_changer.h"
00045
00046 InitializerDismantle::InitializerDismantle(void):
00047 Changer(Both, Subtree, false)
00048 {}
00049
00050 Node * InitializerDismantle::at_block(blockNode * the_block, Order ord) {
00051 if ( ord == Preorder ) {
00052 _blockStack.push(the_block);
00053 } else {
00054 if ( _assgblock.find(the_block) != _assgblock.end() )
00055 the_block->stmts().push_front(_assgblock[the_block]);
00056 assert(_blockStack.top() == the_block);
00057 _blockStack.pop();
00058 }
00059 return the_block;
00060 }
00061
00062 exprNode * InitializerDismantle::eval_or_cast(exprNode * expr, typeNode * type)
00063 {
00064 assert(type);
00065 if ( !expr->no_tdef_type()
00066 || *(expr->no_tdef_type()) != *type )
00067 expr = new castNode((typeNode *) ref_clone_changer::clone(type, false),
00068 expr);
00069 expr->eval();
00070 if ( !expr->value().no_val() ) {
00071 return new constNode(expr->value());
00072 }
00073 return expr;
00074 }
00075
00076 void InitializerDismantle::init_scalar(declNode * the_decl,
00077 exprNode * init) {
00078 init = eval_or_cast(init, the_decl->no_tdef_type());
00079
00080 if ( the_decl->decl_location() == declNode::BLOCK ) {
00081 the_decl->init(NULL);
00082 idNode * id = new idNode(the_decl);
00083 binaryNode * assg = new binaryNode('=', id, init);
00084 assg->type((typeNode *) ref_clone_changer::clone(the_decl->type(),
00085 false));
00086 blockNode * decl_block = _blockStack.top();
00087 if ( _assgblock.find(decl_block) == _assgblock.end() )
00088 _assgblock[decl_block] = new blockNode(NULL, NULL,
00089 decl_block->coord(),
00090 decl_block->coord());
00091 _assgblock[decl_block]->stmts().push_back(new exprstmtNode(assg));
00092 } else if ( the_decl->decl_location() == declNode::TOP ) {
00093 the_decl->init(init);
00094 }
00095 }
00096
00097 initializerNode * InitializerDismantle::init_array(arrayNode * the_array,
00098 expr_list_p & val,
00099 expr_list_p end,
00100 bool inSublist) {
00101 constant array_size;
00102 if ( the_array->dim() ){
00103 the_array->dim()->eval();
00104 array_size = the_array->dim()->value();
00105 }
00106
00107 int count = 1;
00108 initializerNode * result_init = new initializerNode(NULL);
00109
00110 while ( val != end
00111 && ( array_size.no_val()
00112 || count <= array_size.Integer() ) ) {
00113 if ( arrayNode * sub_array =
00114 dynamic_cast<arrayNode *>(the_array->no_tdef_type()) ) {
00115 initializerNode * sub_init = NULL;
00116 if ( initializerNode * cur_val =
00117 dynamic_cast<initializerNode *>(*val) ) {
00118 expr_list_p new_begin = cur_val->exprs().begin();
00119 sub_init = init_array(sub_array, new_begin, cur_val->exprs().end(),
00120 true);
00121 val++;
00122 } else
00123 sub_init = init_array(sub_array, val, end, false);
00124
00125 assert(sub_init);
00126 result_init->exprs().push_back(sub_init);
00127 } else if ( structNode * sub_struct =
00128 dynamic_cast<structNode *>(the_array->no_tdef_type()) ) {
00129 initializerNode * sub_init = NULL;
00130 if ( initializerNode * cur_val =
00131 dynamic_cast<initializerNode *>(*val) ) {
00132 expr_list_p new_begin = cur_val->exprs().begin();
00133 sub_init = init_struct(sub_struct, new_begin, cur_val->exprs().end(),
00134 true);
00135 val++;
00136 } else
00137 sub_init = init_struct(sub_struct, val, end, false);
00138
00139 assert(sub_init);
00140 result_init->exprs().push_back(sub_init);
00141 } else {
00142 if ( initializerNode * init_expr =
00143 dynamic_cast<initializerNode *>(*val) ) {
00144 CBZ::Error(the_array->coord(), "Scalar initialized by list of"
00145 " initial values");
00146 } else {
00147
00148 if ( isStringLiteral(*val) ) {
00149 const char * str = (dynamic_cast<constNode *>(*val))->value().Str();
00150 count += strlen(str);
00151 result_init->exprs().splice(result_init->exprs().end(),
00152 strLit2Init(str)->exprs());
00153 } else {
00154 exprNode * initVal = eval_or_cast(*val, the_array->no_tdef_type());
00155 result_init->exprs().push_back(initVal);
00156 }
00157 }
00158 val++;
00159 }
00160 count++;
00161 }
00162
00163 if ( array_size.no_val() ) {
00164 the_array->dim(new constNode(constant::constant(count-1)));
00165 } else {
00166 while ( count <= array_size.Integer() ) {
00167
00168 if ( arrayNode * sub_array =
00169 dynamic_cast<arrayNode *>(the_array->no_tdef_type()) )
00170 result_init->exprs().push_back(init_array(sub_array, end, end, false));
00171 else if ( structNode * sub_struct =
00172 dynamic_cast<structNode *>(the_array->no_tdef_type()) )
00173 result_init->exprs().push_back(init_struct(sub_struct, end, end,
00174 false));
00175 else {
00176 primNode * elmtType = dynamic_cast<primNode *>(the_array->type());
00177 assert(elmtType);
00178 constant value = constant::cast(elmtType->basic(), constant(0));
00179 result_init->exprs().push_back(new constNode(value));
00180 }
00181 count++;
00182 }
00183 }
00184
00185 if ( val != end && inSublist) {
00186 CBZ::Error(the_array->coord(), "Too many values in initializer list");
00187 }
00188
00189 return result_init;
00190 }
00191
00192 initializerNode * InitializerDismantle::init_struct(structNode * the_struct,
00193 expr_list_p & val,
00194 expr_list_p end,
00195 bool inSublist) {
00196 initializerNode * result_init = new initializerNode(NULL);
00197
00198 suespecNode * the_spec = the_struct->spec();
00199 decl_list_p field = the_spec->fields().begin();
00200 decl_list_p field_end = the_spec->fields().end();
00201
00202 while ( val != end
00203 && field != field_end ) {
00204 if ( arrayNode * sub_array =
00205 dynamic_cast<arrayNode *>((*field)->no_tdef_type()) ) {
00206 initializerNode * sub_init = NULL;
00207 if ( initializerNode * cur_val =
00208 dynamic_cast<initializerNode *>(*val) ) {
00209 expr_list_p new_begin = cur_val->exprs().begin();
00210 sub_init = init_array(sub_array, new_begin, cur_val->exprs().end(),
00211 true);
00212 val++;
00213 } else
00214 sub_init = init_array(sub_array, val, end, false);
00215
00216 assert(sub_init);
00217 result_init->exprs().push_back(sub_init);
00218 } else if ( structNode * sub_struct =
00219 dynamic_cast<structNode *>((*field)->no_tdef_type()) ) {
00220 initializerNode * sub_init = NULL;
00221 if ( initializerNode * cur_val =
00222 dynamic_cast<initializerNode *>(*val) ) {
00223 expr_list_p new_begin = cur_val->exprs().begin();
00224 sub_init = init_struct(sub_struct, new_begin, cur_val->exprs().end(),
00225 true);
00226 val++;
00227 } else
00228 sub_init = init_struct(sub_struct, val, end, false);
00229
00230 assert(sub_init);
00231 result_init->exprs().push_back(sub_init);
00232 } else {
00233 if ( initializerNode * init_expr =
00234 dynamic_cast<initializerNode *>(*val) ) {
00235 CBZ::Error(the_struct->coord(), "Scalar initialized by list of"
00236 " initial values");
00237 } else {
00238
00239 exprNode * initVal = eval_or_cast(*val, (*field)->no_tdef_type());
00240 result_init->exprs().push_back(initVal);
00241 }
00242 val++;
00243 }
00244 field++;
00245 }
00246
00247
00248 while ( field != field_end ) {
00249 if ( arrayNode * sub_array =
00250 dynamic_cast<arrayNode *>((*field)->no_tdef_type()) )
00251 result_init->exprs().push_back(init_array(sub_array, end, end, false));
00252 else if ( structNode * sub_struct =
00253 dynamic_cast<structNode *>((*field)->no_tdef_type()) )
00254 result_init->exprs().push_back(init_struct(sub_struct, end, end, false));
00255 else {
00256 primNode * fieldType = dynamic_cast<primNode*>((*field)->no_tdef_type());
00257 assert(fieldType);
00258 constant value = constant::cast(fieldType->basic(), constant(0));
00259 result_init->exprs().push_back(new constNode(value));
00260 }
00261 field++;
00262 }
00263
00264 if ( val != end && inSublist ) {
00265 CBZ::Error(the_struct->coord(), "Too many values in initializer list");
00266 }
00267
00268 return result_init;
00269 }
00270
00271 bool InitializerDismantle::isStringLiteral(exprNode * the_expr) {
00272 if ( constNode * the_const = dynamic_cast<constNode *>(the_expr) ) {
00273 return the_const->value().is_str();
00274 }
00275 return false;
00276 }
00277
00278 initializerNode * InitializerDismantle::strLit2Init(const char * str) {
00279 initializerNode * newInit = new initializerNode(NULL);
00280 for ( int i = 0; i < strlen(str); i++ ) {
00281 char text[4];
00282 sprintf(text, "'%c'", str[i]);
00283 constNode * newConst = new constNode(constant::constant(str[i]), text);
00284 newConst->type(new primNode(basic_type::Char));
00285 newInit->add_expr(newConst);
00286 }
00287 newInit->add_expr(new constNode(constant::constant('\0')));
00288 return newInit;
00289 }
00290
00291
00292
00293 Node * InitializerDismantle::at_decl(declNode * the_decl, Order ord) {
00294 if ( ord == Preorder ) {
00295 exprNode * initExpr = the_decl->init();
00296 if ( initExpr ) {
00297 if ( isStringLiteral(initExpr)
00298 && the_decl->no_tdef_type()->typ() == Array ) {
00299
00300 char * str = (dynamic_cast<constNode *>(initExpr))->value().Str();
00301 initializerNode * newInit = strLit2Init(str);
00302 initExpr = newInit;
00303 the_decl->init(newInit);
00304 }
00305
00306
00307 if ( initializerNode * the_init
00308 = dynamic_cast<initializerNode *>(initExpr) ) {
00309 typeNode * top_type = the_decl->no_tdef_type();
00310 if ( top_type->is_aggregate() ) {
00311 expr_list_p val = the_init->exprs().begin();
00312 initializerNode * new_init = NULL;
00313 if ( arrayNode * the_array = dynamic_cast<arrayNode *>(top_type) )
00314 new_init = init_array(the_array, val, the_init->exprs().end(),
00315 true);
00316 else if ( structNode * the_struct =
00317 dynamic_cast<structNode *>(top_type) )
00318 new_init = init_struct(the_struct, val, the_init->exprs().end(),
00319 true);
00320 else
00321 assert(false);
00322
00323 assert(new_init);
00324 the_decl->init(new_init);
00325 } else if ( top_type->is_scalar() ) {
00326
00327
00328 if ( the_init->exprs().size() != 1 )
00329 CBZ::Error(the_decl->coord(), "Too many values in initializer"
00330 " list");
00331 if ( the_init->exprs().front()->typ() == Initializer )
00332 CBZ::Error(the_decl->coord(), "Scalar initialized with a list"
00333 " of initial values");
00334
00335 init_scalar(the_decl, the_init->exprs().front());
00336 }
00337 } else {
00338 init_scalar(the_decl, initExpr);
00339 }
00340 }
00341 }
00342 return the_decl;
00343 }