A struct select needs to decypher whether there is an array index necessary in the chain of events. The only kind of assignment that makes sense is a series of struct field selections, array indexings, or (last) a direct variable reference (for the top level struct). This function generates code for the index and returns the resulting symbol, or returns NULL if no dereference is necessary.
| 1243 | // This function generates code for the index and returns the resulting |
| 1244 | // symbol, or returns NULL if no dereference is necessary. |
| 1245 | Symbol * |
| 1246 | ASTstructselect::codegen_index () |
| 1247 | { |
| 1248 | // Must account for array indices farther up the chain. |
| 1249 | ASTNode *node = this; |
| 1250 | Symbol *indexsym = NULL; |
| 1251 | while (node) { |
| 1252 | if (node->nodetype() == variable_ref_node) { |
| 1253 | // Hit final variable ref -- done |
| 1254 | break; |
| 1255 | } |
| 1256 | else if (node->nodetype() == structselect_node) { |
| 1257 | // Hit another struct select -- recurse up |
| 1258 | node = ((ASTstructselect *)node)->lvalue().get(); |
| 1259 | } |
| 1260 | else if (node->nodetype() == index_node) { |
| 1261 | // Hit an array index node -- find the index and recurse |
| 1262 | ASTindex *arrayref = (ASTindex *)node; |
| 1263 | indexsym = arrayref->index()->codegen(); |
| 1264 | // FIXME -- to allow multiple levels of array indexing, |
| 1265 | // this should "append", i.e. multiply, the old index |
| 1266 | // with the new one. |
| 1267 | node = arrayref->lvalue().get(); |
| 1268 | } |
| 1269 | else { |
| 1270 | ASSERT (0); |
| 1271 | } |
| 1272 | } |
| 1273 | |
| 1274 | return indexsym; |
| 1275 | } |
| 1276 | |
| 1277 | |
| 1278 |