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 }