openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

cint_ast.c (21060B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:        cint_ast.c
      8  * Purpose:     CINT AST node functions
      9  */
     10 
     11 #include "cint_ast.h"
     12 #include "cint_config.h"
     13 #include "cint_porting.h"
     14 #include "cint_internal.h"
     15 
     16 
     17 const char* (*cint_ast_get_file_f)(void) = NULL; 
     18 int (*cint_ast_get_line_f)(void) = NULL; 
     19 
     20 
     21 static cint_ast_t* __ast_list = NULL; 
     22 
     23 static cint_ast_t* 
     24 cint_ast_alloc(cint_ast_type_t type)
     25 {
     26     cint_ast_t* ast = CINT_MALLOC(sizeof(*ast)); 
     27 
     28     if (ast == NULL) {
     29         cint_ast_error(NULL, CINT_E_MEMORY, "memory allocation failure"); 
     30         return NULL; 
     31     }
     32     CINT_MEMSET(ast, 0, sizeof(*ast)); 
     33     ast->ntype = type; 
     34 
     35     if(cint_ast_get_file_f) {
     36         ast->file = cint_ast_get_file_f(); 
     37     }
     38     if(cint_ast_get_line_f) {
     39         ast->line = cint_ast_get_line_f(); 
     40     }
     41 
     42 
     43     /* All allocated ASTs are kept in a private list for easier deallocation */
     44     ast->inext = __ast_list; 
     45     __ast_list = ast; 
     46     return ast;
     47 }
     48 
     49 /* 
     50 * Function : cint_ast_free_single
     51 * Decsription : This function
     52 * 1. finds ast and removes it from __ast_list
     53 * 2. frees ast by calling cint_ast_free().
     54 * Usage : This is used in case you want to free an AST immediately after 
     55 * it is used. __ast_list will be freed by cint_ast_free_all() but this is 
     56 * called only after exiting loop scope. 
     57 * When loop count is really large, AST's are not be freed up and RSS increases
     58 * and finally causes out of memory even though it is not used. (SDK-67627)
     59 */
     60 void 
     61 cint_ast_free_single (cint_ast_t* a)
     62 {        
     63    if (__ast_list != NULL) {
     64      if (__ast_list == a) {             /* if "a" is at head of list */
     65         __ast_list = __ast_list->inext;
     66      } else {                           /* search list for "a" */
     67         cint_ast_t* current = __ast_list;
     68         while ((current->inext != NULL) && (current->inext != a)) {
     69           current = current->inext;
     70         }
     71         if (current->inext == a) {
     72           current->inext = current->inext->inext;
     73         }
     74      }
     75    }
     76    cint_ast_free(a);
     77 }
     78 
     79 static void
     80 cint_ast_obj_free(const void *s)
     81 {
     82     if (s) {
     83         CINT_FREE((void *)s);
     84     }
     85 }
     86 
     87 void
     88 cint_ast_free(cint_ast_t* ast)
     89 {
     90     switch (ast->ntype) {
     91     case cintAstString:
     92         cint_ast_obj_free(ast->utype.string.s);
     93         break;
     94     case cintAstFunction:
     95         cint_ast_obj_free(ast->utype.function.name);
     96         cint_ast_obj_free(ast->utype.function.dtp);
     97         break;
     98     case cintAstIdentifier:
     99         cint_ast_obj_free(ast->utype.identifier.s);
    100         break;
    101     case cintAstType:
    102         cint_ast_obj_free(ast->utype.type.s);
    103         break;
    104     default:
    105         break;
    106     }
    107     CINT_FREE(ast); 
    108 }
    109 
    110 void
    111 cint_ast_free_all(void)
    112 {
    113     /* Free all inactive AST nodes on the private list */
    114     cint_ast_t* a;
    115     cint_ast_t* active = NULL;
    116     for(a = __ast_list; a;) {
    117         cint_ast_t* next = a->inext;
    118         if (a->refcount > 0) {
    119             a->inext = active;
    120             active = a;
    121         } else {
    122             cint_ast_free(a);
    123         }
    124         a = next; 
    125     }   
    126     __ast_list = active; 
    127 }       
    128 
    129 cint_ast_t* 
    130 cint_ast_operator(cint_operator_t operator, cint_ast_t* left, cint_ast_t* right)
    131 {
    132     cint_ast_t* ast = cint_ast_alloc(cintAstOperator); 
    133     ast->utype.operator.op = operator; 
    134     ast->utype.operator.left = left; 
    135     ast->utype.operator.right = right; 
    136     return ast;
    137 }
    138 
    139 cint_ast_t* 
    140 cint_ast_integer(int i)
    141 {
    142     cint_ast_t* ast = cint_ast_alloc(cintAstInteger);
    143     ast->utype.integer.i = i; 
    144     return ast; 
    145 }
    146 
    147 #if CINT_CONFIG_INCLUDE_LONGLONGS == 1
    148 cint_ast_t* 
    149 cint_ast_long_long(long long i)
    150 {
    151     cint_ast_t* ast = cint_ast_alloc(cintAstLongLong);
    152     ast->utype._longlong.i = i; 
    153     return ast; 
    154 }
    155 
    156 #endif
    157 
    158 #if CINT_CONFIG_INCLUDE_DOUBLES == 1
    159 cint_ast_t* 
    160 cint_ast_double(double d)
    161 {
    162     cint_ast_t* ast = cint_ast_alloc(cintAstDouble);
    163     ast->utype._double.d = d; 
    164     return ast; 
    165 }
    166 #endif
    167 
    168 cint_ast_t*
    169 cint_ast_string(const char* s)
    170 {
    171     cint_ast_t* ast = cint_ast_alloc(cintAstString); 
    172     ast->utype.string.s = CINT_STRDUP(s);         
    173     return ast;
    174 }
    175 
    176 cint_ast_t*
    177 cint_ast_identifier(const char* s)
    178 {
    179     cint_ast_t* ast = cint_ast_alloc(cintAstIdentifier); 
    180     ast->utype.identifier.s = CINT_STRDUP(s); 
    181     return ast;
    182 }
    183 
    184 cint_ast_t*
    185 cint_ast_type(const char* s)
    186 {
    187     cint_ast_t* ast = cint_ast_alloc(cintAstType); 
    188     ast->utype.type.s = CINT_STRDUP(s); 
    189     return ast;
    190 }
    191 
    192 cint_ast_t*
    193 cint_ast_declaration(void)
    194 {
    195     cint_ast_t* ast = cint_ast_alloc(cintAstDeclaration); 
    196     return ast;
    197 }
    198 
    199 cint_ast_t*
    200 cint_ast_initializer(cint_ast_t* inits)
    201 {
    202     cint_ast_t* ast = cint_ast_alloc(cintAstInitializer); 
    203     ast->utype.initializer.initializers = inits; 
    204     return ast; 
    205 }
    206 
    207 cint_ast_t*
    208 cint_ast_function(cint_ast_t* f, cint_ast_t* params)
    209 {
    210     cint_ast_t* ast = cint_ast_alloc(cintAstFunction); 
    211     if(f) {
    212         if(f->ntype != cintAstIdentifier) {
    213             /* Only identifiers can be specified for function calls */
    214             CINT_PRINTF("**error: Cannot parse function ast: "); 
    215             cint_ast_dump(f, 0); 
    216             CINT_PRINTF("\n\n"); 
    217             return NULL; 
    218         }
    219         ast->utype.function.name = CINT_STRDUP(f->utype.identifier.s); 
    220     }   
    221     ast->utype.function.parameters = params; 
    222     return ast; 
    223 }
    224 
    225 cint_ast_t* 
    226 cint_ast_function_def(void)
    227 {
    228     cint_ast_t* ast = cint_ast_alloc(cintAstFunctionDef); 
    229     return ast; 
    230 }
    231 
    232 cint_ast_t* 
    233 cint_ast_structure_def(cint_ast_t* name, cint_ast_t* members)
    234 {
    235     cint_ast_t* ast = cint_ast_alloc(cintAstStructureDef); 
    236     ast->utype.structuredef.name = name; 
    237     ast->utype.structuredef.members = members; 
    238     return ast; 
    239 }
    240 
    241 
    242 cint_ast_t* 
    243 cint_ast_elist(cint_ast_t* first)
    244 {
    245     cint_ast_t* ast = cint_ast_alloc(cintAstElist); 
    246     ast->utype.elist.list = first; 
    247     return ast; 
    248 }
    249 
    250 cint_ast_t* 
    251 cint_ast_while(cint_ast_t* expr, cint_ast_t* statements, int order)
    252 {
    253     cint_ast_t* ast = cint_ast_alloc(cintAstWhile); 
    254     ast->utype._while.condition = expr; 
    255     ast->utype._while.statements = statements; 
    256     ast->utype._while.order = order; 
    257     return ast;
    258 }
    259 
    260 cint_ast_t* 
    261 cint_ast_for(cint_ast_t* pre, cint_ast_t* cond, cint_ast_t* post, cint_ast_t* statements)
    262 {
    263     cint_ast_t* ast = cint_ast_alloc(cintAstFor); 
    264     ast->utype._for.pre = pre; 
    265     ast->utype._for.condition = cond; 
    266     ast->utype._for.post = post; 
    267     ast->utype._for.statements = statements; 
    268     return ast; 
    269 }
    270 
    271 cint_ast_t* 
    272 cint_ast_if(cint_ast_t* expr, cint_ast_t* statements, cint_ast_t* _else)
    273 {
    274     cint_ast_t* ast = cint_ast_alloc(cintAstIf); 
    275     ast->utype._if.condition = expr; 
    276     ast->utype._if.statements = statements; 
    277     ast->utype._if._else = _else; 
    278     return ast; 
    279 }
    280 
    281 cint_ast_t* cint_ast_continue(void)
    282 {
    283     cint_ast_t* ast = cint_ast_alloc(cintAstContinue); 
    284     return ast; 
    285 }
    286 
    287 cint_ast_t* 
    288 cint_ast_break(void)
    289 {
    290     cint_ast_t* ast = cint_ast_alloc(cintAstBreak); 
    291     return ast; 
    292 }
    293 
    294 cint_ast_t*
    295 cint_ast_return(cint_ast_t* expr)
    296 {
    297     cint_ast_t* ast = cint_ast_alloc(cintAstReturn); 
    298     ast->utype._return.expression = expr; 
    299     return ast; 
    300 }
    301 
    302 cint_ast_t* 
    303 cint_ast_print(cint_ast_t* expr)
    304 {
    305     cint_ast_t* ast = cint_ast_alloc(cintAstPrint); 
    306     ast->utype.print.expression = expr; 
    307     return ast; 
    308 }
    309 
    310 cint_ast_t* 
    311 cint_ast_cint(cint_ast_t* args)
    312 {
    313     cint_ast_t* ast = cint_ast_alloc(cintAstCint); 
    314     ast->utype.cint.arguments = args; 
    315     return ast; 
    316 }
    317 
    318 cint_ast_t*
    319 cint_ast_switch(cint_ast_t* expr, cint_ast_t* statements)
    320 {
    321     cint_ast_t* ast = cint_ast_alloc(cintAstSwitch); 
    322     ast->utype._switch.expression = expr; 
    323     ast->utype._switch.statements = statements;         
    324     return ast; 
    325 }
    326 
    327 cint_ast_t*
    328 cint_ast_case(cint_ast_t* expr, cint_ast_t* statements)
    329 {
    330     cint_ast_t* ast = cint_ast_alloc(cintAstCase); 
    331     ast->utype._switch.expression = expr; 
    332     ast->utype._switch.statements = statements;         
    333     return ast; 
    334 }
    335 
    336 cint_ast_t* 
    337 cint_ast_enumerator(cint_ast_t* identifier, cint_ast_t* value)
    338 {
    339     cint_ast_t* ast = cint_ast_alloc(cintAstEnumerator); 
    340     ast->utype.enumerator.identifier = identifier; 
    341     ast->utype.enumerator.value = value; 
    342     return ast; 
    343 }
    344     
    345 cint_ast_t* 
    346 cint_ast_enumdef(cint_ast_t* identifier, cint_ast_t* enumerators)
    347 {
    348     cint_ast_t* ast = cint_ast_alloc(cintAstEnumDef); 
    349     ast->utype.enumdef.identifier = identifier; 
    350     ast->utype.enumdef.enumerators = enumerators; 
    351     return ast; 
    352 }
    353 
    354 cint_ast_t*
    355 cint_ast_empty(void)
    356 {
    357     cint_ast_t* ast = cint_ast_alloc(cintAstEmpty); 
    358     return ast; 
    359 }
    360 
    361 cint_ast_t*
    362 cint_ast_statement_with_no_effect(cint_ast_t* ast)
    363 {
    364     if(!(ast &&
    365         (ast->ntype == cintAstIdentifier) &&
    366         (ast->utype.identifier.s) &&
    367         (!CINT_STRCMP(ast->utype.identifier.s, "exit")||
    368          !CINT_STRCMP(ast->utype.identifier.s, "quit")))) {
    369         cint_warn(NULL, 0, "statement with no effect");
    370     }
    371 
    372     return ast;
    373 }
    374 
    375 #define L_SUFFIX 1
    376 #define U_SUFFIX 2
    377 #define LL_SUFFIX 4
    378 #define BAD_SUFFIX 8
    379 
    380 static int
    381 _cint_ast_int_suffix(const char* s)
    382 {
    383     int c,suffix;
    384 
    385     suffix = 0;
    386     while ((c=*s++) != 0) {
    387         switch (c) {
    388         case 'l':
    389         case 'L':
    390             if (suffix & (LL_SUFFIX)) {
    391                 suffix |= BAD_SUFFIX;
    392             } else if (suffix & (L_SUFFIX)) {
    393                 suffix &= ~L_SUFFIX;
    394                 suffix |= LL_SUFFIX;
    395             } else {
    396                 suffix |= L_SUFFIX;
    397             }
    398             break;
    399         case 'u':
    400         case 'U':
    401             if (suffix & (U_SUFFIX)) {
    402                 suffix |= BAD_SUFFIX;
    403             } else {
    404                 suffix |= U_SUFFIX;
    405             }
    406             break;
    407         }
    408     }
    409     return suffix;
    410 }
    411 
    412 cint_ast_t*
    413 cint_ast_constant(const char* s, cint_ast_const_t ctype)
    414 {
    415     switch (ctype) {
    416     case cintAstConstHex:
    417     case cintAstConstOctal:
    418     case cintAstConstDecimal:
    419         {
    420             int suffix = _cint_ast_int_suffix(s);
    421 
    422             if ((suffix & BAD_SUFFIX) == 0) {
    423                 if (suffix & LL_SUFFIX) {
    424 #if CINT_CONFIG_INCLUDE_LONGLONGS == 1
    425                     long long i = 0; 
    426                     if(cint_ctolli(s, &i) == 0) {
    427                         return cint_ast_long_long(i); 
    428                     }
    429 #endif
    430                 } else {
    431                     long i = 0; 
    432                     if(cint_ctoi(s, &i) == 0) {
    433                         return cint_ast_integer(i); 
    434                     }
    435                 }
    436             }
    437         }
    438         break;
    439     case cintAstConstChar:
    440         {
    441             int i = 0; 
    442 
    443             if(cint_chartoi(s, &i) == 0) {
    444                 return cint_ast_integer(i); 
    445             }
    446         }
    447         break;
    448     case cintAstConstFloat:
    449 #if CINT_CONFIG_INCLUDE_DOUBLES == 1
    450         {      
    451             double d; 
    452             if(cint_ctod(s, &d) == 0) {
    453                 return cint_ast_double(d); 
    454             }
    455         }
    456 #endif
    457         break;
    458     }
    459     cint_ast_error(NULL, CINT_E_BAD_EXPRESSION, "unrecognized integer format"); 
    460     return NULL; 
    461 }
    462 
    463 int 
    464 cint_ast_append(cint_ast_t* root, cint_ast_t* tail)
    465 {
    466     int i = 0; 
    467     cint_ast_t* p;
    468 
    469     /* Protect against loops in the AST list. Normally this should not
    470        happen, but if it does, do not go into an infinite loop. */
    471     for(p = root; p && p->next && p != p->next; p = p->next) {
    472         if (tail != NULL && p == tail) {
    473             /* error: forms a loop */
    474             cint_ast_error(tail, CINT_E_BAD_AST, "loop in AST");
    475             return 0;
    476         }
    477         i++;
    478     }
    479     if (p) {
    480         p->next = tail;
    481         i++;
    482     }
    483     return i; 
    484 }
    485 
    486 int
    487 cint_ast_count(cint_ast_t* root)
    488 {
    489     if(root) {
    490         return cint_ast_append(root, NULL); 
    491     }   
    492     else {
    493         return 0; 
    494     }
    495 }
    496 
    497 cint_ast_t* 
    498 cint_ast_last(cint_ast_t* root)
    499 {
    500     cint_ast_t* p; 
    501     for(p = root; p && p->next; p = p->next); 
    502     return p; 
    503 }
    504 
    505 int
    506 cint_ast_int(cint_ast_t* a)
    507 {
    508     return CINT_AST(a, Integer) ? a->utype.integer.i : 0 ;
    509 }
    510 
    511      
    512 const char *
    513 cint_ast_str(cint_ast_t* a)
    514 {
    515     return CINT_AST(a, String) ? a->utype.string.s : NULL;
    516 }
    517 
    518 cint_ast_t* 
    519 cint_ast_ternary(cint_ast_t* expression, cint_ast_t* t, cint_ast_t* f)
    520 {
    521     cint_ast_t *ast = cint_ast_operator(cintOpQuestion, expression, t);
    522     if (ast) {
    523         ast->utype.operator.extra = f;
    524     }
    525     return ast;
    526 }
    527 
    528 cint_ast_t* 
    529 cint_ast_comma(cint_ast_t* left, cint_ast_t* right)
    530 {
    531     cint_ast_t *ast = NULL;
    532 
    533     if (left) {
    534         if (left->ntype == cintAstElist) {
    535             cint_ast_append(left->utype.elist.list, right); 
    536             ast = left; 
    537         } else {
    538             ast = cint_ast_elist(left);
    539             if (ast) {
    540                 cint_ast_append(ast->utype.elist.list, right);
    541             }
    542         }
    543     }
    544     return ast;    
    545 }
    546 
    547 cint_ast_t* 
    548 cint_ast_declaration_init(cint_ast_t* spec, cint_ast_t* init)
    549 {
    550     /* Assign the type in spec to all declarations in the list */
    551     cint_ast_t* p; 
    552     for(p = init; p; p = p->next) {
    553         switch(p->ntype) {
    554         case cintAstDeclaration:
    555             p->utype.declaration.type = spec;
    556             break; 
    557         case cintAstFunctionDef:
    558             if (p->utype.functiondef.declaration && 
    559                 p->utype.functiondef.declaration->ntype ==
    560                 cintAstDeclaration) {
    561                 p->utype.functiondef.declaration->utype.declaration.type =
    562                     spec;
    563             }
    564             break;
    565         default:
    566             break;
    567         }
    568     }
    569     return init;
    570 }
    571 
    572 
    573 cint_ast_t* 
    574 cint_ast_declarator_init(cint_ast_t* decl, cint_ast_t* init)
    575 {
    576     if (decl && decl->ntype == cintAstDeclaration) {
    577         decl->utype.declaration.init = init;
    578     }
    579     return decl;
    580 }
    581 
    582 
    583 cint_ast_t* 
    584 cint_ast_struct_declaration(cint_ast_t* qual, cint_ast_t* decl)
    585 {
    586     if (decl && decl->ntype == cintAstDeclaration) {
    587         decl->utype.declaration.type = qual;
    588     }
    589     return decl;
    590 }
    591 
    592 cint_ast_t* 
    593 cint_ast_pointer_declarator(cint_ast_t* ptr, cint_ast_t* decl)
    594 {
    595     if (decl) {
    596         switch(decl->ntype) {
    597         case cintAstDeclaration:
    598             decl->utype.declaration.pcount = cint_ast_int(ptr);
    599             break; 
    600         case cintAstFunctionDef:
    601             if (decl->utype.functiondef.declaration) {
    602                 decl->utype.functiondef.declaration->utype.declaration.pcount =
    603                     cint_ast_int(ptr);
    604             }
    605             break; 
    606         default: break;
    607             /* Error */
    608         }
    609     }
    610     return decl;        
    611 }
    612 
    613 cint_ast_t* 
    614 cint_ast_identifier_declarator(cint_ast_t* ident)
    615 {
    616     cint_ast_t *ast;
    617 
    618     ast = cint_ast_declaration();
    619     if (ast) {
    620         ast->utype.declaration.identifier = ident;
    621     }
    622 
    623     return ast;
    624 }
    625 
    626 cint_ast_t* 
    627 cint_ast_array_declarator(cint_ast_t* decl, cint_ast_t* len)
    628 {
    629     if(decl) {
    630         if(decl->utype.declaration.num_dimension_initializers >=
    631             CINT_CONFIG_ARRAY_DIMENSION_LIMIT) {
    632                 cint_ast_error(
    633                     decl, 
    634                     CINT_E_BAD_AST, 
    635                     "dimension limit exceeded");
    636                 return NULL;
    637         }
    638         if (decl->ntype == cintAstDeclaration) {
    639             int index = decl->utype.declaration.num_dimension_initializers;
    640             decl->utype.declaration.dimension_initializers[index] = len;
    641             decl->utype.declaration.num_dimension_initializers++;
    642         }
    643     }
    644     return decl;
    645 }
    646 
    647 
    648 cint_ast_t* 
    649 cint_ast_function_declarator(cint_ast_t* decl, cint_ast_t* param)
    650 {
    651     cint_ast_t *ast = cint_ast_function_def();
    652 
    653     if (ast) {
    654         ast->utype.functiondef.declaration = decl; 
    655         ast->utype.functiondef.parameters = param;
    656     }
    657     return ast;
    658 }
    659 
    660 cint_ast_t* 
    661 cint_ast_pointer_indirect(cint_ast_t* val)
    662 {
    663     if (CINT_AST(val, Integer)) {
    664         val->utype.integer.i++;
    665 #if CINT_CONFIG_INCLUDE_LONGLONGS == 1
    666     } else if (CINT_AST(val, LongLong)) {
    667         val->utype._longlong.i++;
    668 #endif
    669     }
    670 
    671     return val;
    672 }
    673 
    674 cint_ast_t* 
    675 cint_ast_parameter_declaration_append(cint_ast_t* spec, cint_ast_t* decl)
    676 {
    677     if (decl && decl->ntype == cintAstDeclaration) {
    678         decl->utype.declaration.type = spec;
    679     }
    680 
    681     return decl;
    682 }
    683 
    684 cint_ast_t* 
    685 cint_ast_parameter_declaration(cint_ast_t* decl)
    686 {
    687     cint_ast_t *ast = cint_ast_declaration();
    688 
    689     if (ast) {
    690         ast->utype.declaration.type = decl;
    691     }
    692 
    693     return ast;
    694 }
    695 
    696 cint_ast_t* 
    697 cint_ast_compound_statement(cint_ast_t* stmt)
    698 {
    699     /* compound_statements get their own scope operators */              
    700     cint_ast_t* ss = cint_ast_operator(cintOpOpenBrace, 0, 0); 
    701     cint_ast_t* se = cint_ast_operator(cintOpCloseBrace, 0, 0); 
    702 
    703     if (ss) {
    704         /* Enclose all statements within new scope */
    705         ss->next = stmt; 
    706         /* Append closing scope to statement list */
    707         cint_ast_append(ss, se);
    708     }
    709 
    710     /* Return statement list */
    711     return ss;
    712 }
    713 
    714 cint_ast_t* 
    715 cint_ast_function_definition(cint_ast_t* ty,
    716                              cint_ast_t* decl, cint_ast_t* stmt)
    717 {
    718     if (CINT_AST(decl, FunctionDef)) {
    719         if (decl->utype.functiondef.declaration &&
    720             /* signed, unsigned is detected as CINT_AST(ty, Integer) */
    721             (CINT_AST(ty, Type) || CINT_AST(ty, Integer))) {
    722             decl->utype.functiondef.declaration->utype.declaration.type = ty;
    723         }
    724         decl->utype.functiondef.statements = stmt; 
    725     }
    726     return decl;
    727 }
    728 
    729 /* Modify reference count for AST and all children by 'delta' */
    730 void
    731 cint_ast_touch(cint_ast_t* ast, int delta)
    732 {
    733     cint_ast_t* p;
    734     int dimension;
    735 
    736     for (p=ast; p; p=p->next) {
    737         if ((p == CINT_AST_PTR_VOID) || (p == CINT_AST_PTR_AUTO)) {
    738             /* special node types are terminal */
    739             break;
    740         }
    741         p->refcount += delta;
    742         switch(p->ntype) {
    743         case cintAstDeclaration:
    744             cint_ast_touch(p->utype.declaration.type, delta);
    745             for (dimension = 0; 
    746                 dimension < p->utype.declaration.num_dimension_initializers; 
    747                 ++dimension) {
    748                 cint_ast_touch(
    749                     p->utype.declaration.dimension_initializers[dimension],
    750                     delta);
    751             }
    752             cint_ast_touch(p->utype.declaration.identifier, delta);
    753             cint_ast_touch(p->utype.declaration.init, delta);
    754             break;
    755         case cintAstInitializer:
    756             cint_ast_touch(p->utype.initializer.initializers, delta);
    757             break;
    758         case cintAstOperator:
    759             cint_ast_touch(p->utype.operator.left, delta);
    760             cint_ast_touch(p->utype.operator.right, delta);
    761             cint_ast_touch(p->utype.operator.extra, delta);
    762             break;
    763         case cintAstFunction:
    764             cint_ast_touch(p->utype.function.parameters, delta);
    765             break;
    766         case cintAstFunctionDef:
    767             cint_ast_touch(p->utype.functiondef.declaration, delta);
    768             cint_ast_touch(p->utype.functiondef.parameters, delta);
    769             cint_ast_touch(p->utype.functiondef.statements, delta);
    770             break;
    771         case cintAstStructureDef:
    772             cint_ast_touch(p->utype.structuredef.name, delta);
    773             cint_ast_touch(p->utype.structuredef.members, delta);
    774             break;
    775         case cintAstElist:
    776             cint_ast_touch(p->utype.elist.list, delta);
    777             break;
    778         case cintAstWhile:
    779             cint_ast_touch(p->utype._while.condition, delta);
    780             cint_ast_touch(p->utype._while.statements, delta);
    781             break;
    782         case cintAstFor:
    783             cint_ast_touch(p->utype._for.pre, delta);
    784             cint_ast_touch(p->utype._for.condition, delta);
    785             cint_ast_touch(p->utype._for.post, delta);
    786             cint_ast_touch(p->utype._for.statements, delta);
    787             break;
    788         case cintAstIf:
    789             cint_ast_touch(p->utype._if.condition, delta);
    790             cint_ast_touch(p->utype._if.statements, delta);
    791             cint_ast_touch(p->utype._if._else, delta);
    792             break;
    793         case cintAstReturn:
    794             cint_ast_touch(p->utype._return.expression, delta);
    795             break;
    796         case cintAstSwitch:
    797             cint_ast_touch(p->utype._switch.expression, delta);
    798             cint_ast_touch(p->utype._switch.statements, delta);
    799             break;
    800         case cintAstCase:
    801             cint_ast_touch(p->utype._case.expression, delta);
    802             cint_ast_touch(p->utype._case.statements, delta);
    803             break;
    804         case cintAstEnumerator:
    805             cint_ast_touch(p->utype.enumerator.identifier, delta);
    806             cint_ast_touch(p->utype.enumerator.value, delta);
    807             break;
    808         case cintAstEnumDef:
    809             cint_ast_touch(p->utype.enumdef.identifier, delta);
    810             cint_ast_touch(p->utype.enumdef.enumerators, delta);
    811             break;
    812         case cintAstPrint:
    813             cint_ast_touch(p->utype.print.expression, delta);
    814             break;
    815         case cintAstCint:
    816             cint_ast_touch(p->utype.cint.arguments, delta);
    817             break;
    818         default:
    819             break;
    820         }
    821     }
    822         
    823 }