1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77/* 78** NAME 79** 80** ASTP_COM.C 81** 82** FACILITY: 83** 84** Interface Definition Language (IDL) Compiler 85** 86** ABSTRACT: 87** 88** Common routines shared between the AST builder modules. 89** 90** VERSION: DCE 1.0 91** 92*/ 93 94#include <nidl.h> 95#include <nametbl.h> 96#include <errors.h> 97#include <astp.h> 98#include <nidlmsg.h> 99#include <nidl_y.h> 100#include <checker.h> 101#include <message.h> 102#include <backend.h> 103#include <command.h> 104#include <irep.h> 105 106static AST_type_n_t *AST_propagate_typedef ( 107 parser_location_p location, 108 AST_type_n_t *type_node_ptr, 109 ASTP_declarator_n_t *declarator_ptr, 110 ASTP_attributes_t *attributes 111); 112 113static AST_array_n_t *AST_propagate_array_type ( 114 parser_location_p location, 115 AST_type_n_t *type_node_ptr, 116 AST_type_n_t *element_type_node_ptr, 117 ASTP_declarator_op_n_t *declarator_op_ptr 118); 119 120static void ASTP_verify_non_anonymous ( 121 parser_location_p location, 122 AST_type_n_t *type, 123 ASTP_declarator_n_t *declarator_ptr 124); 125 126 127 128/* 129 * A S T P _ a d d _ n a m e _ b i n d i n g 130 * ========================================== 131 * 132 * This routine add a binding between the name and 133 * node specified. If the name is already declared 134 * the NIDL_NAMEALRDEC error message is displayed. 135 */ 136 137void ASTP_add_name_binding 138( 139 parser_location_p location, 140 NAMETABLE_id_t name, 141 void *AST_node 142) 143{ 144 char const *identifier; /* place to receive the identifier text pointer */ 145 ASTP_node_t const *binding; /* place to recieve binding */ 146 char const *filename; /* place to receive the filename text pointer */ 147 int issue_error; 148 int issue_case_warning ATTRIBUTE_UNUSED; 149 150 /* 151 * Check to see if there is already a constant binding to the name. 152 * If there is, then we can't make this declaration because constants 153 * are implemented as #define which are global. 154 */ 155 binding = NAMETABLE_lookup_binding(name); 156 if ((binding != NULL) && (binding->fe_info->node_kind == fe_constant_n_k)) 157 issue_error = true; 158 else 159 /* Add the name to nametable and bind it to the specified node */ 160 issue_error = !NAMETABLE_add_binding (name, AST_node); 161 162 /* 163 * If the name binding failed, output the error message. 164 */ 165 if (issue_error) 166 { 167 /* FIXME binding can become NULL */ 168 169 assert(NULL != binding); 170 171 NAMETABLE_id_to_string (name, &identifier); 172 173 /* Select message and file information as present */ 174 if ((binding->fe_info != (fe_info_t *)NULL) && 175 (binding->fe_info->source_line != 0) && 176 (binding->fe_info->file != STRTAB_NULL_STR)) 177 { 178 STRTAB_str_to_string(binding->fe_info->file, &filename); 179 log_error (location->lineno, NIDL_NAMEPREVDECLAT, identifier, 180 filename, binding->fe_info->source_line, NULL); 181 } 182 else 183 log_error (location->lineno, NIDL_NAMEALRDEC, identifier, NULL); 184 } 185 186 return; 187} 188 189/*-----------------------------------------------------------------------*/ 190/* 191 * A S T P _ v a l i d a t e _ f o r w a r d _ r e f 192 * ================================================= 193 * 194 * This routine verifies that the specified type 195 * is not a forward reference to an incomplete struct/union 196 * by tag. This is to prevent the generation of nonstandard C code 197 * that may not compile. Forward references to incomplete types 198 * are only allowed in contexts where allocation size information is 199 * not needed (e.g. a pointer to the type, or in a typedef). If 200 * the type passed to this routine is not yet completely defined, then 201 * an error will be issued. 202 */ 203 204void ASTP_validate_forward_ref 205( 206 parser_location_p location, 207 AST_type_n_t *type 208) 209{ 210 /* 211 * Check that the base type is not an incomplete struct/union 212 */ 213 if (AST_DEF_AS_TAG_SET(type) && 214 ((type->kind == AST_disc_union_k) || 215 (type->kind == AST_structure_k)) && 216 (type->type_structure.structure == NULL)) 217 { 218 char const *identifier; 219 NAMETABLE_id_to_string(type->fe_info->tag_name, &identifier); 220 log_error(location->lineno, NIDL_DEFNOTCOMP, identifier, NULL); 221 } 222} 223 224/* 225 * A S T P _ v a l i d a t e _ f o r w a r d _ r e f _ s c o p e 226 * ============================================================= 227 * 228 * This routine verifies that the specified type is not a forward reference 229 * to an incomplete type by tag that by (ANSI C) definition is in a different 230 * lexical scope than the eventual type and tag definition. This is to prevent 231 * the generation of nonstandard C code that may not compile. Forward 232 * references to incomplete types must be at the same scoping level. 233 */ 234 235static void ASTP_validate_forward_ref_scope 236( 237 parser_location_p location, 238 AST_type_n_t *type, 239 ASTP_node_t *parent_node 240) 241{ 242 /* 243 * Check that the base type is not an incomplete struct/union 244 */ 245 if (AST_DEF_AS_TAG_SET(type) 246 && type->type_structure.structure == NULL 247 && parent_node->fe_info->node_kind == fe_parameter_n_k) 248 { 249 /* Forward tag reference in this declaration is not ANSI C compliant */ 250 char const *identifier; 251 NAMETABLE_id_to_string(type->fe_info->tag_name, &identifier); 252 log_warning(location->lineno, NIDL_FWDTAGREF, identifier, NULL); 253 } 254} 255 256/*-----------------------------------------------------------------------*/ 257 258/* 259 * A S T P _ c h a s e _ p t r _ t o _ k i n d 260 * =========================================== 261 * 262 * Chase a pointer type until a specified 263 * "kind" type is found. 264 * 265 * Inputs: 266 * type_node The starting type node which SHOULD 267 * be a pointer kind. 268 * 269 * kind The "kind" of type node we're 270 * searching for. 271 * 272 * Outputs: 273 * 274 * 275 * Function Value: 276 * Pointer to the type node which contains 277 * the kind. If search failed, NULL is returned. 278 * If successful, returned type node's fe_info 279 * pointer count if set to the number of pointer 280 * nodes traversed. 281 */ 282AST_type_n_t *ASTP_chase_ptr_to_kind 283( 284 AST_type_n_t *type_node, 285 AST_type_k_t kind 286) 287{ 288 AST_type_n_t *tp; 289 short int pointer_count; 290 291 for (tp= type_node, pointer_count = 0; 292 (tp->kind != kind ) && (tp->kind == AST_pointer_k); 293 tp = tp->type_structure.pointer->pointee_type, pointer_count++) 294 { 295 /* Chase pointer until we find the "kind" type node */ 296 } 297 298 if (tp->kind != kind) 299 { 300 tp = NULL; 301 } 302 else 303 { 304 tp->fe_info->pointer_count = pointer_count; 305 } 306 307 return tp; 308} 309 310/*-------------------------------------------------------------------*/ 311 312/* 313 * A S T P _ c h a s e _ p t r _ t o _ t y p e 314 * =========================================== 315 * 316 * Chase a pointer type until a non-pointer is 317 * is found, i.e. until the base type is found. 318 * 319 * Inputs: 320 * type_node The starting type node which SHOULD 321 * be a pointer kind. 322 * 323 * Outputs: 324 * 325 * 326 * Function Value: 327 * Pointer to the type node which lives 328 * at the end of the chain of pointers. 329 * The returned type node's fe_info pointer_count 330 * field is set to the number of pointer nodes 331 * traversed. 332 */ 333AST_type_n_t *ASTP_chase_ptr_to_type 334( 335 AST_type_n_t *type_node 336) 337{ 338 AST_type_n_t *tp; 339 short int pointer_count; 340 341 for (tp= type_node, pointer_count = 0; 342 (tp->kind == AST_pointer_k); 343 tp = tp->type_structure.pointer->pointee_type, pointer_count++) 344 { 345 /* Chase pointer until we find the base type node */ 346 } 347 348 tp->fe_info->pointer_count = pointer_count; 349 350 return tp; 351} 352 353/*-------------------------------------------------------------------*/ 354 355/* 356 * A S T _ c l o n e _ c o n s t a n t 357 * =================================== 358 * 359 * Clone a constant node. 360 * 361 */ 362 363AST_constant_n_t *AST_clone_constant 364( 365 parser_location_p location, 366 AST_constant_n_t *constant_node_p 367) 368{ 369 AST_constant_n_t *new_const_node_p; 370 371 /* 372 * Create constant node of the appropriate kind and 373 * replicate value and fe_info constant kind information 374 */ 375 376 new_const_node_p = AST_constant_node (location, constant_node_p->kind); 377 378 switch (new_const_node_p->kind) 379 { 380 case AST_boolean_const_k: 381 new_const_node_p->value.boolean_val = 382 constant_node_p->value.boolean_val; 383 break; 384 385 case AST_char_const_k: 386 new_const_node_p->value.char_val = 387 constant_node_p->value.char_val; 388 break; 389 390 case AST_int_const_k: 391 new_const_node_p->value.int_val = 392 constant_node_p->value.int_val; 393 break; 394 395 case AST_string_const_k: 396 new_const_node_p->value.string_val = 397 constant_node_p->value.string_val; 398 break; 399 400 default: 401 break; 402 } 403 404 /* Get the constant kind from the front end info */ 405 new_const_node_p->fe_info->fe_type_id = 406 constant_node_p->fe_info->fe_type_id; 407 new_const_node_p->fe_info->type_specific.const_kind = 408 constant_node_p->fe_info->type_specific.const_kind; 409 410 return new_const_node_p; 411} 412 413/*----------------------------------------------------------------------*/ 414 415/* 416 * A S T _ c o n c a t _ e l e m e n t 417 * 418 * A generic list handling routine that concatenates a element (which 419 * may be itself a singly-linked list) to a singly-linked list of the 420 * same type. 421 * 422 * Assumptions: 423 * All element types have the next and last pointers as the first 424 * fields in the structure. 425 * 426 * Function Value: 427 * The updated list header. 428 */ 429 430ASTP_node_t *AST_concat_element 431( 432 ASTP_node_t *list_head, 433 ASTP_node_t *element 434) 435{ 436 /* Check for null element. Grammer will sometimes call us this way */ 437 if (element == NULL) 438 { 439 return list_head; 440 } 441 442 /* List is empty. Link in new element or list */ 443 if (list_head == NULL) 444 { 445 list_head = element; 446 return list_head; 447 } 448 449 /* Only one item on list. Link in new element or list */ 450 if (list_head->last == NULL) 451 { 452 if (element->last == NULL) 453 { 454 list_head->last = element; 455 list_head->next = element; 456 return list_head; 457 } 458 459 list_head->last = element->last; 460 list_head->next = element; 461 return list_head; 462 } 463 464 /* Multiple items exist on list. */ 465 list_head->last->next = element; 466 if (element->last != NULL) 467 { 468 list_head->last = element->last; 469 } 470 else 471 { 472 list_head->last = element; 473 } 474 475 return list_head; 476 477} 478 479/*---------------------------------------------------------------------*/ 480 481/* 482 * A S T P _ l o o k u p _ b i n d i n g 483 * ========================================== 484 * 485 * This routine looks up a binding of a particular 486 * AST node. 487 * 488 * Inputs: 489 * name Name identifier to lookup. 490 * node_kind The node kind the binding should be. 491 * noforward_ref True, if forward references are not 492 * expected. 493 * Outputs: 494 * None. 495 * 496 * Function Value: 497 * If successful, the node bound to the name of the 498 * particular type, otherwise NULL is returned. 499 */ 500 501ASTP_node_t *ASTP_lookup_binding 502( 503 parser_location_p location, 504 NAMETABLE_id_t name, 505 fe_node_k_t node_kind, 506 boolean noforward_ref 507 508) 509{ 510 ASTP_node_t *bound_node; 511 char const *identifier; 512 513 /* 514 * Lookup binding 515 */ 516 bound_node = (ASTP_node_t *) NAMETABLE_lookup_binding(name); 517 518 /* 519 * If not found tell them if the caller wants 520 * us to. This is for parameters and field 521 * array bound attributes which can be 522 * forward referenced. 523 */ 524 if ((bound_node == NULL) && noforward_ref) 525 { 526 NAMETABLE_id_to_string (name, &identifier); 527 log_error(location->lineno, NIDL_NAMENOTFND, identifier, NULL) ; 528 } 529#if 0 530 /* If they are looking for a type and we got an ORPC interface, chase 531 * through to the underlying type information */ 532 if (node_kind == fe_type_n_k && bound_node && 533 bound_node->fe_info->node_kind == fe_interface_n_k && 534 AST_OBJECT_SET((AST_interface_n_t*)bound_node)) 535 return bound_node->type_structure; 536 bound_node = (ASTP_node_t*)((AST_interface_n_t*)bound_node)->orpc_intf_type; 537#endif 538 /* 539 * If binding node of wrong type, return NULL, and tell them. 540 */ 541 if ((bound_node != NULL) && 542 (bound_node->fe_info->node_kind != node_kind)) 543 { 544 /* If forward references are not allowed, output error message now */ 545 if (noforward_ref) 546 { 547 NAMETABLE_id_to_string (name, &identifier); 548 549 switch (node_kind) 550 { 551 case fe_constant_n_k: 552 log_error(location->lineno, NIDL_NAMENOTCONST, identifier, 553 NULL) ; 554 break; 555 556 case fe_type_n_k: 557 log_error(location->lineno, NIDL_NAMENOTTYPE, identifier, 558 NULL) ; 559 break; 560 561 case fe_field_n_k: 562 log_error(location->lineno, NIDL_NAMENOTFIELD, identifier, 563 NULL) ; 564 break; 565 566 case fe_parameter_n_k: 567 log_error(location->lineno, NIDL_NAMENOTPARAM, identifier, 568 NULL) ; 569 break; 570 571 default: 572 break; 573 } 574 575 /* State where the name was previously declared, if known */ 576 if ((bound_node->fe_info->source_line != 0) && 577 (bound_node->fe_info->file != STRTAB_NULL_STR)) 578 { 579 char const *filename; /* place to receive the filename text pointer */ 580 STRTAB_str_to_string(bound_node->fe_info->file, &filename); 581 log_error (location->lineno, NIDL_NAMEPREVDECLAT, identifier, 582 filename, bound_node->fe_info->source_line, NULL); 583 } 584 } 585 586 /* Return Null, so caller doesn't use wrong node type that we found */ 587 bound_node = NULL; 588 } 589 590 return bound_node; 591} 592 593/*-----------------------------------------------------------------------*/ 594 595/* 596 * A S T _ p o i n t e r _ n o d e 597 * =============================== 598 * 599 * Create and initialize a pointer node 600 */ 601 602AST_pointer_n_t * AST_pointer_node 603( 604 parser_location_p location, 605 AST_type_n_t * pointee 606) 607{ 608 AST_pointer_n_t * pointer_node_ptr; 609 610 pointer_node_ptr = NEW (AST_pointer_n_t); 611 pointer_node_ptr->pointee_type = pointee; 612 ASTP_set_fe_info (location, &pointer_node_ptr->fe_info, fe_pointer_n_k); 613 return pointer_node_ptr; 614} 615 616/*---------------------------------------------------------------------*/ 617 618/* 619 * A S T _ d e c l a r a t o r s _ t o _ t y p e s 620 * =============================================== 621 * 622 * For each of the linked declarator nodes, allocate a 623 * type node and collapse the declarator node to the 624 * type node, forming a list of type pointer nodes. 625 * 626 * INPUTS: 627 * type_ptr Pointer to type node. 628 * declarators_ptr Pointer to list of declarator nodes. 629 * 630 * OUTPUTS: 631 * None. 632 * 633 * FUNCTION VALUE: 634 * Pointer to a list of type node pointers. 635 * 636 * NOTES: 637 * The original type node is used for the first declarator node. 638 * 639 */ 640 641AST_type_p_n_t *AST_declarators_to_types 642( 643 parser_location_p location, 644 AST_interface_n_t * ifp, 645 AST_type_n_t *type_ptr, 646 ASTP_declarator_n_t *declarators_ptr, 647 ASTP_attributes_t *attributes 648) 649{ 650 AST_type_p_n_t 651 *type_p_list = NULL, /* List of type pointer nodes */ 652 *type_p_ptr; /* Created for each type node */ 653 654 ASTP_declarator_n_t 655 gen_declarator, /* Generated declarator for use as base */ 656 *base_dp = NULL, /* Base declarator used for the base */ 657 /* type name and generates other types. */ 658 *dp; /* For traversing through declarators */ 659 660 AST_type_n_t 661 *base_type = type_ptr; /* Base type used to generate other all */ 662 /* other types derived in this typedef. */ 663 664 /* 665 * Look for a simple declarator to use when generating the base type node. 666 * All other types are generated from the base type. 667 */ 668 for (dp = declarators_ptr; 669 dp != (ASTP_declarator_n_t *) NULL; 670 dp = dp->next) 671 { 672 if (dp->next_op == NULL) 673 { 674 /* 675 * Save the base declarator so we can skip over it during our second 676 * pass over the declarators. 677 */ 678 base_dp = dp; 679 680 /* 681 * If the original type is a struct/union with tag and this is a simple 682 * declarator (not a pointer, array or function), then we must do some 683 * special processing to set the name in the type node for tag 684 * references to the type name. The tag name is only stored in the 685 * structure_node pointed to by the type node. 686 */ 687 if ((type_ptr->fe_info->tag_ptr != NULL) && 688 (type_ptr->fe_info->tag_ptr->name == NAMETABLE_NIL_ID)) 689 type_ptr->fe_info->tag_ptr->name = base_dp->name; 690 691 /* 692 * All that's needed in this loop so exit loop 693 */ 694 break; 695 } 696 } 697 698 /* 699 * If we did not find a base declarator to use and the base type is not 700 * named, then generate a named base declarator from which to build all 701 * of the more complicated types. 702 */ 703 if ((base_dp == NULL) && /* No simple declarator */ 704 (base_type->name == NAMETABLE_NIL_ID) && /* Base type is anonymous */ 705 ((base_type->kind == AST_structure_k) || /* a struct or union */ 706 (base_type->kind == AST_disc_union_k)) && 707 (base_type->fe_info->tag_name == NAMETABLE_NIL_ID)) /* union/struct doesn't have a tag name */ 708 { 709 base_dp = &gen_declarator; 710 base_dp->name = AST_generate_name(ifp,""); 711 base_dp->next = NULL; 712 base_dp->last = NULL; 713 base_dp->next_op = NULL; 714 base_dp->last_op = NULL; 715 base_dp->fe_info = NULL; 716 } 717 718 /* 719 * create a type for the simple type declared in this typedef and 720 * use it to generate the types for other declarators in this typedef. 721 */ 722 if (base_dp != NULL) 723 { 724 ASTP_attributes_t local_attributes; /* copy of attributes that */ 725 local_attributes = *attributes; /* we can manipulate */ 726 727 /* Create a type pointer node */ 728 type_p_ptr = AST_type_ptr_node(location); 729 730 /* 731 * Propagate declarator to the type node, merge in any attributes, and 732 * Link type node to type pointer node, and form type pointer list. 733 */ 734 base_type = AST_propagate_typedef(location, type_ptr, base_dp, &local_attributes); 735 type_p_ptr->type = base_type; 736 type_p_list = (AST_type_p_n_t *)AST_concat_element ( 737 (ASTP_node_t *)type_p_list, (ASTP_node_t *)type_p_ptr); 738 739 /* 740 * If we are processing a generated declarator, ignore all pointer 741 * attributes 742 */ 743 if (base_dp == &gen_declarator) 744 ASTP_CLR_ATTR(&local_attributes,ASTP_IGNORE|ASTP_PTR|ASTP_REF| 745 ASTP_UNIQUE|ASTP_STRING); 746 747 /* Set the type attributes to the new type node */ 748 AST_set_type_attrs(location, type_p_ptr->type, &local_attributes); 749 750 /* 751 * If there is an associated DEF_AS_TAG type node, then make sure to 752 * set on that type node as well. 753 */ 754 if (type_p_ptr->type->fe_info->tag_ptr != NULL) 755 AST_set_type_attrs(location, type_p_ptr->type->fe_info->tag_ptr, &local_attributes); 756 } 757 758 /* 759 * For each of the declarators create a new type as described by the 760 * declarators. These types will all be dervied from the base type. 761 */ 762 for (dp = declarators_ptr; 763 dp != (ASTP_declarator_n_t *) NULL; 764 dp = dp->next) 765 { 766 /* Skip over the base declarator because it's been processed */ 767 if (dp == base_dp) continue; 768 769 /* Create a type pointer node */ 770 type_p_ptr = AST_type_ptr_node(location); 771 772 /* 773 * Propagate declarator to the type node, merge in any attributes, and 774 * Link type node to type pointer node, and form type pointer list. 775 */ 776 type_p_ptr->type = AST_propagate_typedef(location, base_type, dp, attributes); 777 type_p_list = (AST_type_p_n_t *)AST_concat_element ( 778 (ASTP_node_t *)type_p_list, (ASTP_node_t *)type_p_ptr); 779 780 /* Set the type attributes to the new type node */ 781 AST_set_type_attrs(location, type_p_ptr->type, attributes); 782 783 /* 784 * If there is an associated DEF_AS_TAG type node, then make sure to 785 * set on that type node as well. 786 */ 787 if (type_p_ptr->type->fe_info->tag_ptr != NULL) 788 AST_set_type_attrs(location, type_p_ptr->type->fe_info->tag_ptr, attributes); 789 } 790 791 /* Free temporary declarators list */ 792 ASTP_free_declarators(declarators_ptr); 793 794 return type_p_list; 795} 796 797/*---------------------------------------------------------------------*/ 798 799/* 800 * 801 * A S T _ p r o p a g a t e _ a r r a y _ t y p e 802 * =============================================== 803 * 804 * Create the AST array node and propagate 805 * the array index information pointed to by 806 * the declarator node to the array node 807 * 808 * Note, that in the declarator node, the 809 * array index is a linked list of AST Private 810 * array index nodes. With the AST array node, 811 * it is implemented as a vector. 812 */ 813 814AST_array_n_t *AST_propagate_array_type 815( 816 parser_location_p location, 817 AST_type_n_t *type_node_ptr, 818 AST_type_n_t *element_type_node_ptr, 819 ASTP_declarator_op_n_t *declarator_op_ptr 820) 821{ 822 AST_array_n_t *array_node_ptr; 823 ASTP_array_index_n_t *index_ptr; 824 AST_array_index_n_t *array_index_node; 825 unsigned short index_count; 826 boolean is_conformant = FALSE; 827 828 /* Create the array node, creating linking in a element type node */ 829 array_node_ptr = AST_array_node(location, element_type_node_ptr); 830 831 /* Propagate the array indice information */ 832 833 /* Count the number of dimensions */ 834 for (index_ptr = declarator_op_ptr->op_info.indices, index_count=0; 835 index_ptr != NULL; 836 index_ptr = index_ptr->next, index_count++) 837 {}; 838 839 array_node_ptr->index_count = index_count; 840 841 /* Allocate (and initialize) the array index vector */ 842 array_node_ptr->index_vec = AST_array_index_node(location, index_count); 843 844 /* 845 * Fill in the index information pointed 846 * to by the array node and set the FIXED flags. 847 */ 848 for (index_ptr = declarator_op_ptr->op_info.indices, 849 array_index_node = array_node_ptr->index_vec; 850 index_ptr != NULL; 851 index_ptr=index_ptr->next, array_index_node++) 852 { 853 if (index_ptr->lower_bound != NULL) 854 { 855 array_index_node->lower_bound = index_ptr->lower_bound; 856 AST_SET_FIXED_LOWER(array_index_node); 857 } 858 else 859 { 860 is_conformant = TRUE; 861 } 862 863 if (index_ptr->upper_bound != NULL) 864 { 865 array_index_node->upper_bound = index_ptr->upper_bound; 866 AST_SET_FIXED_UPPER(array_index_node); 867 } 868 else 869 { 870 is_conformant = TRUE; 871 } 872 873 } 874 875 /* 876 * If any dimension of the array is not fixed, 877 * set the conformant flag in the type node 878 * specifying an unfixed allocation size 879 */ 880 if (is_conformant) 881 { 882 AST_SET_CONFORMANT(type_node_ptr); 883 } 884 885 return array_node_ptr; 886} 887 888/*---------------------------------------------------------------------*/ 889 890/* 891 * 892 * A S T _ p r o p a g a t e _ t y p e _ a t t r s 893 * =============================================== 894 * 895 * Check for the presence of the REF, PTR or UNIQUE attribute 896 * and set the specified flag in the parameter or 897 * field's type node if present. 898 * We need to clone the type if the new type 899 * is (build by AST_propagate_type()) is a simple declarator. 900 * 901 * This processing is done here (called from 902 * propagate_types() to minimize on the cloning, 903 * since we know we just created a new anonymous 904 * type (no clone) or used the current type (clone). 905 * 906 * We also propagate type attributes which are also 907 * field/parameter/arm attributes to the field/parameter/arm node. 908 * These currently are string, small, and ignore. 909 */ 910 911static AST_type_n_t *AST_propagate_type_attrs 912( 913 parser_location_p location, 914 AST_type_n_t *type_node_ptr, 915 ASTP_attributes_t *attributes, 916 boolean needs_clone ATTRIBUTE_UNUSED, 917 ASTP_node_t *parent_node 918) 919{ 920 AST_type_n_t *return_type; /* type node to return */ 921 ASTP_attr_flag_t ptr_attrs = 0; 922 923 return_type = type_node_ptr; 924 925 /* 926 * Only one of [unique], [ptr], or [ref] can be specified. 927 * If that is not the case, output an error stating that the 928 * two specified are conflicting. 929 */ 930 if (attributes != NULL) 931 { 932 /* Copy the iid_is name */ 933 return_type->iid_is_name = attributes->iid_is_name; 934 935 /* 936 * If any pointer attrs are set, make sure only one of them is 937 * specified. 938 */ 939 ptr_attrs = (attributes->attr_flags) & (ASTP_UNIQUE|ASTP_PTR|ASTP_REF); 940 if ((ptr_attrs != 0) && 941 !((ptr_attrs == ASTP_REF) || (ptr_attrs == ASTP_PTR) || 942 (ptr_attrs == ASTP_UNIQUE))) 943 { 944 ASTP_attr_flag_t attr1 = ASTP_REF; 945 ASTP_attr_flag_t attr2 = ASTP_PTR; 946 if (!ASTP_TEST_ATTR(attributes,ASTP_REF)) attr1 = ASTP_UNIQUE; 947 if (!ASTP_TEST_ATTR(attributes,ASTP_PTR)) attr2 = ASTP_UNIQUE; 948 log_error(location->lineno, NIDL_CONFLICTATTR, 949 KEYWORDS_lookup_text(AST_attribute_to_token(&attr1)), 950 KEYWORDS_lookup_text(AST_attribute_to_token(&attr2)), NULL); 951 } 952 953 /* 954 * Handle V1 attributes specified on an instance, by propagating to 955 * the type node where they are expected. Since this is propagation 956 * from instance to type, only do it for anonymous types. If the 957 * type is not anonymous the V1 attributes should have been set 958 * in the typedef in which it is declared. Since we don't clear 959 * the attribute, an error will occur in the routine AST_set_flags. 960 */ 961 if (return_type->name == NAMETABLE_NIL_ID) 962 { 963 if (ASTP_TEST_ATTR(attributes,ASTP_UNALIGN)) 964 AST_SET_UNALIGN(return_type); 965 if (ASTP_TEST_ATTR(attributes,ASTP_SMALL)) 966 AST_SET_SMALL(return_type); 967 if (ASTP_TEST_ATTR(attributes,ASTP_STRING0)) 968 AST_SET_STRING0(return_type); 969 if (ASTP_TEST_ATTR(attributes,ASTP_V1_ENUM)) 970 AST_SET_V1_ENUM(return_type); 971 if (ASTP_TEST_ATTR(attributes,ASTP_SWITCH_TYPE)) 972 { 973 /* 974 * Valid only on non-encapsulated union type 975 * on a field or parameter instance. 976 */ 977 if (return_type->kind == AST_disc_union_k 978 && return_type->type_structure.disc_union->discrim_name 979 == NAMETABLE_NIL_ID 980 && (parent_node->fe_info->node_kind == fe_parameter_n_k 981 || parent_node->fe_info->node_kind == fe_field_n_k)) 982 { 983 return_type->type_structure.disc_union->discrim_type 984 = ASTP_switch_type; 985 ASTP_CLR_ATTR(attributes,ASTP_SWITCH_TYPE); 986 } 987 } 988 989 /* Remove the type-attributes, as they are now on the type */ 990 ASTP_CLR_ATTR(attributes,ASTP_UNALIGN|ASTP_SMALL|ASTP_STRING0|ASTP_V1_ENUM); 991 } 992 } 993 994 /* 995 * Do type attributes for parameter nodes 996 */ 997 if (parent_node->fe_info->node_kind == fe_parameter_n_k) 998 { 999 /* 1000 * Process explicit [ptr], [ref], or [unique] 1001 */ 1002 if (ptr_attrs != 0) 1003 { 1004 /* valid for anonymous pointer or array types only */ 1005 if (((return_type->name == NAMETABLE_NIL_ID) && 1006 (return_type->kind == AST_pointer_k)) || 1007 (return_type->kind == AST_array_k)) 1008 { 1009 } 1010 else 1011 { 1012 /* 1013 * Output error, PTR or UNIQUE not valid on parameter 1014 * being passed by value. 1015 */ 1016 log_error(location->lineno, NIDL_PRMBYREF, 1017 KEYWORDS_lookup_text(AST_attribute_to_token(&ptr_attrs)), 1018 NULL); 1019 } 1020 1021 } 1022 else 1023 { 1024 /* 1025 * Process default. [REF] is implied for a parameter 1026 * that is an anonymous pointer or 1027 * an array type without any attributes. 1028 */ 1029 if (((return_type->name == NAMETABLE_NIL_ID) && 1030 (return_type->kind == AST_pointer_k)) || 1031 (return_type->kind == AST_array_k)) 1032 { 1033 /* 1034 * Don't set [ref] on void* types because it is either a 1035 * context handle, or checker will issue an error on it. 1036 * Also, don't set [ref] on interface* types. 1037 */ 1038 if (!((return_type->kind == AST_pointer_k) && 1039 (return_type->type_structure.pointer->pointee_type->kind == AST_void_k) )) 1040 { 1041 if (return_type->type_structure.pointer->pointee_type->kind != AST_interface_k) 1042 AST_SET_REF(((AST_parameter_n_t*)parent_node)); 1043 } 1044 } 1045 else 1046 { 1047 /* 1048 * Not anonymous array or pointer, so propagate ptr, ref, & 1049 * unique attributes from type to parameter 1050 * 1051 */ 1052 if (AST_PTR_SET(return_type)) 1053 AST_SET_PTR((AST_parameter_n_t *)parent_node); 1054 if (AST_REF_SET(return_type)) 1055 AST_SET_REF((AST_parameter_n_t *)parent_node); 1056 if (AST_UNIQUE_SET(return_type)) 1057 AST_SET_UNIQUE((AST_parameter_n_t *)parent_node); 1058 } 1059 } /* End pointer attributes processing */ 1060 1061 /* 1062 * Propagate small, string, and string0 attributes to the parameter node 1063 */ 1064 if (AST_SMALL_SET(return_type)) 1065 AST_SET_SMALL((AST_parameter_n_t *)parent_node); 1066 1067 if (AST_STRING_SET(return_type)) 1068 AST_SET_STRING((AST_parameter_n_t *)parent_node); 1069 1070 if (AST_STRING0_SET(return_type)) 1071 AST_SET_STRING0((AST_parameter_n_t *)parent_node); 1072 1073 } /* End if parameter node */ 1074 1075 /* 1076 * Do the type attributes for field and arm nodes 1077 */ 1078 if ((parent_node->fe_info->node_kind == fe_field_n_k) || 1079 (parent_node->fe_info->node_kind == fe_arm_n_k)) 1080 { 1081 if (ptr_attrs == 0) 1082 { 1083 /* 1084 * Propagate ptr, ref, or unique to the arm and field nodes. 1085 */ 1086 if (AST_PTR_SET(return_type)) 1087 { 1088 if (parent_node->fe_info->node_kind == fe_field_n_k) 1089 AST_SET_PTR((AST_field_n_t *)parent_node); 1090 else 1091 AST_SET_PTR((AST_arm_n_t *)parent_node); 1092 } 1093 if (AST_REF_SET(return_type)) 1094 { 1095 if (parent_node->fe_info->node_kind == fe_field_n_k) 1096 AST_SET_REF((AST_field_n_t *)parent_node); 1097 else 1098 AST_SET_REF((AST_arm_n_t *)parent_node); 1099 } 1100 if (AST_UNIQUE_SET(return_type)) 1101 { 1102 if (parent_node->fe_info->node_kind == fe_field_n_k) 1103 AST_SET_UNIQUE((AST_field_n_t *)parent_node); 1104 else 1105 AST_SET_UNIQUE((AST_arm_n_t *)parent_node); 1106 } 1107 } 1108 else /* Attributes specified, make sure pointer is anonymous */ 1109 { 1110 /* Only valid for anonymous pointers */ 1111 if (return_type->name != NAMETABLE_NIL_ID) 1112 { 1113 if (ASTP_TEST_ATTR(attributes,ASTP_REF)) 1114 log_error(location->lineno,NIDL_REFATTRPTR, NULL); 1115 if (ASTP_TEST_ATTR(attributes,ASTP_PTR)) 1116 log_error(location->lineno,NIDL_PTRATTRPTR, NULL); 1117 if (ASTP_TEST_ATTR(attributes,ASTP_UNIQUE)) 1118 log_error(location->lineno,NIDL_UNIQATTRPTR, NULL); 1119 } 1120 } /* End pointer attributes processing */ 1121 1122 /* 1123 * Propagate small, string and string0 to the arm and field nodes. 1124 */ 1125 if (AST_SMALL_SET(return_type)) 1126 { 1127 if (parent_node->fe_info->node_kind == fe_field_n_k) 1128 AST_SET_SMALL((AST_field_n_t *)parent_node); 1129 else 1130 AST_SET_SMALL((AST_arm_n_t *)parent_node); 1131 } 1132 1133 if (AST_STRING_SET(return_type)) 1134 { 1135 if (parent_node->fe_info->node_kind == fe_field_n_k) 1136 AST_SET_STRING((AST_field_n_t *)parent_node); 1137 else 1138 AST_SET_STRING((AST_arm_n_t *)parent_node); 1139 } 1140 1141 if (AST_STRING0_SET(return_type)) 1142 { 1143 if (parent_node->fe_info->node_kind == fe_field_n_k) 1144 AST_SET_STRING0((AST_field_n_t *)parent_node); 1145 else 1146 AST_SET_STRING0((AST_arm_n_t *)parent_node); 1147 } 1148 1149 /* 1150 * Propagate ignore to the field node. 1151 */ 1152 if (AST_IGNORE_SET(return_type) && 1153 (parent_node->fe_info->node_kind == fe_field_n_k)) 1154 { 1155 AST_SET_IGNORE((AST_field_n_t *)parent_node); 1156 } 1157 1158 } /* End if field/arm node */ 1159 1160 return return_type; 1161} 1162 1163/*---------------------------------------------------------------------*/ 1164 1165/* 1166 * 1167 * A S T _ p r o p a g a t e _ t y p e d e f 1168 * ========================================== 1169 * 1170 * Propagate a declarator type to the new type node defined 1171 * with the TYPEDEF keyword. The new type is allocated and 1172 * initialized based upon the declarator and the specified 1173 * type node. 1174 */ 1175 1176static AST_type_n_t *AST_propagate_typedef 1177( 1178 parser_location_p location, 1179 AST_type_n_t *type_node_ptr, 1180 ASTP_declarator_n_t *declarator_ptr, 1181 ASTP_attributes_t *attributes 1182) 1183{ 1184 AST_type_n_t *return_type; /* type node to return */ 1185 AST_type_n_t *current_type; /* type node to return */ 1186 ASTP_declarator_op_n_t *dop; /* declarator operation ptr */ 1187 1188 /* If there is no declarator operation, we need only copy the type */ 1189 if (declarator_ptr->next_op == NULL) 1190 { 1191 /* 1192 * If the type is anonymous, not a base type, and 1193 * isn't identified by a struct/union tag, then we 1194 * can just use it to create the declaration. 1195 */ 1196 if ((type_node_ptr->name == NAMETABLE_NIL_ID) && 1197 !type_is_base(type_node_ptr) && 1198 !AST_DEF_AS_TAG_SET(type_node_ptr)) 1199 { 1200 return_type = type_node_ptr; 1201 } 1202 else 1203 { 1204 return_type = AST_type_node(location, type_node_ptr->kind); 1205 return_type->type_structure = type_node_ptr->type_structure; 1206 return_type->flags = type_node_ptr->flags; 1207 return_type->xmit_as_type = type_node_ptr->xmit_as_type; 1208 /* 1209 * The result type, if [transmit_as], should not inherit attributes 1210 * from the base type that only affect transmissible types, because 1211 * the result type is not transmissible, it is the presented type. 1212 */ 1213 if (ASTP_TEST_ATTR(attributes, ASTP_TRANSMIT_AS)) 1214 { 1215 AST_CLR_STRING(return_type); AST_CLR_STRING0(return_type); 1216 AST_CLR_UNIQUE(return_type); AST_CLR_REF(return_type); 1217 AST_CLR_IGNORE(return_type); AST_CLR_SMALL(return_type); 1218 AST_CLR_CONTEXT_RD(return_type);AST_CLR_PTR(return_type); 1219 } 1220 } 1221 1222 /* 1223 * For simple declarators, if the base type is named, set 1224 * the defined_as pointer of the result type to the named type. 1225 */ 1226 if ((type_node_ptr->name != NAMETABLE_NIL_ID) && 1227 !AST_DEF_AS_TAG_SET(type_node_ptr)) 1228 return_type->defined_as = type_node_ptr; 1229 /* 1230 * Do processing for possibly forward referenced tags. 1231 * 1) Propagate the incomplete, tag_ptr, and tag_name fields of the fe_info. 1232 * 2) Make sure that the DEF_AS_TAG bit is clear. 1233 * 3) If the original type was incomplete, make sure that this type 1234 * is added to the tag reference list for later processing. 1235 */ 1236 return_type->fe_info->tag_ptr = type_node_ptr->fe_info->tag_ptr; 1237 return_type->fe_info->tag_name = type_node_ptr->fe_info->tag_name; 1238 if (FE_TEST(type_node_ptr->fe_info->flags,FE_INCOMPLETE)) 1239 { 1240 FE_SET(return_type->fe_info->flags,FE_INCOMPLETE); 1241 ASTP_save_tag_ref(type_node_ptr->fe_info->tag_name, 1242 type_node_ptr->kind,return_type); 1243 } 1244 } 1245 else 1246 { 1247 return_type = type_node_ptr; 1248 /* Loop through declarator operations to generate the result type */ 1249 for (dop = declarator_ptr->next_op; dop; dop = dop->next_op) 1250 { 1251 /* Specify the result type depending upon the declarator */ 1252 current_type = return_type; 1253 switch (dop->op_kind) 1254 { 1255 case AST_array_k: /* Array declarator */ 1256 return_type = AST_type_node(location, dop->op_kind); 1257 return_type->type_structure.array = 1258 AST_propagate_array_type(location, 1259 return_type, current_type, dop); 1260 break; 1261 1262 case AST_pointer_k: /* Pointer declarator */ 1263 { 1264 int i; 1265 1266 /* Create the pointer node for each STAR specified */ 1267 for (i = dop->op_info.pointer_count; i > 0; i--) 1268 { 1269 boolean is_void = (current_type->kind == AST_void_k); 1270 return_type = AST_type_node(location, dop->op_kind); 1271 return_type->type_structure.pointer = 1272 AST_pointer_node(location, current_type); 1273 current_type = return_type; 1274 1275 /* 1276 * Do not use [pointer_default] attribute for the following: 1277 * types with [transmit_as] attribute 1278 * types with [context_handle] attribute 1279 * void * types (they must be context handles) 1280 * toplevel pointer with [ptr], [ref], or [unique] 1281 * [local] interfaces 1282 */ 1283 if (ASTP_TEST_ATTR(attributes,ASTP_TRANSMIT_AS)) continue; 1284 if (ASTP_TEST_ATTR(attributes,ASTP_CONTEXT)) continue; 1285 if (is_void) continue; 1286 if ((dop->next_op == NULL) && (i == 1) && 1287 (ASTP_TEST_ATTR(attributes,ASTP_PTR|ASTP_REF| 1288 ASTP_UNIQUE) != 0)) 1289 continue; 1290 if (current_type->type_structure.pointer->pointee_type->kind == AST_interface_k) 1291 continue; 1292 /* 1293 * If none of the above exceptions apply, obtain the 1294 * pointer class from the default for the module, if 1295 * any. 1296 */ 1297 switch (the_interface->pointer_default) 1298 { 1299 case 0: /* No interface default */ 1300 if (!AST_LOCAL_SET(the_interface)) 1301 { 1302 char const *identifier; 1303 NAMETABLE_id_to_string ( 1304 declarator_ptr->name, &identifier); 1305 log_warning(location->lineno, 1306 NIDL_MISSPTRCLASS, identifier, 1307 NULL); 1308 AST_SET_PTR(return_type); /* default: [ptr] */ 1309 } 1310 break; 1311 case ASTP_PTR: AST_SET_PTR(return_type); break; 1312 case ASTP_REF: AST_SET_REF(return_type); break; 1313 case ASTP_UNIQUE:AST_SET_UNIQUE(return_type); break; 1314 default: /* shouldn't get here */ 1315 error(NIDL_INTERNAL_ERROR, __FILE__, __LINE__); 1316 } 1317 } 1318 break; 1319 } 1320 1321 case AST_function_k: /* Function declarator */ 1322 return_type = AST_type_node(location, dop->op_kind); 1323 return_type->type_structure.function = 1324 AST_function_node(location, 1325 current_type, declarator_ptr->name, 1326 dop->op_info.routine_params); 1327 break; 1328 1329 default: /* Shouldn't get here */ 1330 error(NIDL_INTERNAL_ERROR, __FILE__, __LINE__); 1331 break; 1332 } 1333 1334 /* 1335 * Do processing for possibly forward referenced tags. 1336 * 1) Propagate the incomplete and tag_ptr fields of the fe_info. 1337 * 2) Make sure that the REF_AS_TAG bit is clear. 1338 * 3) If the original type was incomplete, make sure that this type 1339 * is added to the tag reference list for later processing. 1340 */ 1341 return_type->fe_info->tag_ptr = type_node_ptr->fe_info->tag_ptr; 1342 return_type->fe_info->tag_name = type_node_ptr->fe_info->tag_name; 1343 if (FE_TEST(type_node_ptr->fe_info->flags,FE_INCOMPLETE)) 1344 { 1345 FE_SET(return_type->fe_info->flags,FE_INCOMPLETE); 1346 ASTP_save_tag_ref(type_node_ptr->fe_info->tag_name, 1347 type_node_ptr->kind,return_type); 1348 } 1349 } 1350 } 1351 1352 /* Set the type node name to the declarator's name */ 1353 return_type->name = declarator_ptr->name; 1354 1355 /* Add name to nametable and bind to new type */ 1356 ASTP_add_name_binding (location, return_type->name, return_type); 1357 1358 return return_type; 1359} 1360 1361/*---------------------------------------------------------------------*/ 1362 1363/* 1364 * 1365 * A S T _ p r o p a g a t e _ t y p e 1366 * =================================== 1367 * 1368 * Given a type and a declarator this function returns a 1369 * type representing the combination of the specified type and 1370 * declarator. If the result is "simple" type, the original 1371 * type_ptr is returned. If the result is a "complex" type, a 1372 * new type node is allocated and initialized. 1373 */ 1374 1375AST_type_n_t *AST_propagate_type 1376( 1377 parser_location_p location, 1378 AST_type_n_t *type_node_ptr, 1379 ASTP_declarator_n_t *declarator_ptr, 1380 ASTP_attributes_t *attributes, 1381 ASTP_node_t *parent_node 1382) 1383{ 1384 AST_type_n_t *return_type; /* type node to return */ 1385 AST_type_n_t *current_type; /* type node to return */ 1386 ASTP_declarator_op_n_t *dop; /* declarator operation ptr */ 1387 enum 1388 { 1389 simple_type, 1390 complex_type 1391 } last_op_kind; /* New type is either simple or complex type */ 1392 1393 return_type = type_node_ptr; 1394 last_op_kind = simple_type; /* If no declarator_ops, then simple_type */ 1395 1396 ASTP_validate_forward_ref_scope(location, type_node_ptr, parent_node); 1397 1398 /* Loop through declarator operations to generate the result type */ 1399 for (dop = declarator_ptr->next_op; dop; dop = dop->next_op) 1400 { 1401 last_op_kind = complex_type; /* Assume complex */ 1402 1403 /* Specify the result type depending upon the declarator */ 1404 current_type = return_type; 1405 switch (dop->op_kind) 1406 { 1407 case AST_array_k: /* Array declarator */ 1408 ASTP_validate_forward_ref(location, current_type); 1409 return_type = AST_type_node(location, dop->op_kind); 1410 return_type->type_structure.array = 1411 AST_propagate_array_type(location, 1412 return_type, current_type, dop); 1413 break; 1414 1415 case AST_pointer_k: /* Pointer declarator */ 1416 { 1417 int i; 1418 1419 /* Create the pointer node for each STAR specified */ 1420 for (i = dop->op_info.pointer_count; i > 0; i--) 1421 { 1422 boolean is_void = (current_type->kind == AST_void_k); 1423 1424 ASTP_verify_non_anonymous(location, current_type, declarator_ptr); 1425 1426 return_type = AST_type_node(location, dop->op_kind); 1427 return_type->type_structure.pointer = 1428 AST_pointer_node(location, current_type); 1429 current_type = return_type; 1430 1431 /* 1432 * Do not use [pointer_default] attribute for the following: 1433 * operation results (are always [ptr]), 1434 * constants 1435 * types with [transmit_as] attribute 1436 * types with [context_handle] attribute 1437 * void * types (they must be context handles) 1438 * toplevel pointer with with [ptr], [ref] or [unique] 1439 * toplevel anonymous param pointers 1440 * [local] interfaces 1441 */ 1442 if (parent_node->fe_info->node_kind == fe_operation_n_k) 1443 continue; 1444 if (parent_node->fe_info->node_kind == fe_constant_n_k) 1445 continue; 1446 if (ASTP_TEST_ATTR(attributes,ASTP_TRANSMIT_AS)) continue; 1447 if (ASTP_TEST_ATTR(attributes,ASTP_CONTEXT)) continue; 1448 if (is_void) continue; 1449 if ((dop->next_op == NULL) && (i == 1) && (ASTP_TEST_ATTR( 1450 attributes,ASTP_PTR|ASTP_REF|ASTP_UNIQUE) != 0)) 1451 continue; 1452 if ((dop->next_op == NULL) && (i == 1) && 1453 (parent_node->fe_info->node_kind == fe_parameter_n_k)) 1454 continue; 1455 if (current_type->type_structure.pointer->pointee_type->kind == AST_interface_k) 1456 continue; 1457 1458 /* 1459 * If we passed all of the exceptions, obtain the pointer 1460 * class from the default, and add to pointer. 1461 */ 1462 switch (the_interface->pointer_default) 1463 { 1464 case 0: /* No interface default */ 1465 if (!AST_LOCAL_SET(the_interface)) 1466 { 1467 char const *identifier; 1468 NAMETABLE_id_to_string ( 1469 declarator_ptr->name, &identifier); 1470 log_warning(location->lineno, NIDL_MISSPTRCLASS, 1471 identifier, NULL); 1472 AST_SET_PTR(return_type); /* default: [ptr] */ 1473 } 1474 break; 1475 case ASTP_PTR: AST_SET_PTR(return_type); break; 1476 case ASTP_REF: AST_SET_REF(return_type); break; 1477 case ASTP_UNIQUE:AST_SET_UNIQUE(return_type); break; 1478 default: /* shouldn't get here */ 1479 error(NIDL_INTERNAL_ERROR, __FILE__, __LINE__); 1480 } 1481 } 1482 break; 1483 } 1484 1485 case AST_function_k: /* Function declarator */ 1486 ASTP_validate_forward_ref(location, current_type); 1487 return_type = AST_type_node(location, dop->op_kind); 1488 return_type->type_structure.function = 1489 AST_function_node(location, 1490 current_type, declarator_ptr->name, 1491 dop->op_info.routine_params); 1492 break; 1493 1494 default: /* Shouldn't get here */ 1495 error(NIDL_INTERNAL_ERROR, __FILE__, __LINE__); 1496 break; 1497 } 1498 } 1499 1500 /* 1501 * Set the special (REF, PTR, UNIQUE) field/parameter/arm attributes 1502 * to the type node, and propagate the appropriate type attributes 1503 * back to the field/parameter/arm node. 1504 */ 1505 return_type = 1506 AST_propagate_type_attrs(location, return_type, attributes, 1507 (boolean)(last_op_kind == simple_type), 1508 (ASTP_node_t *)parent_node); 1509 1510 return return_type; 1511} 1512 1513/*---------------------------------------------------------------------*/ 1514 1515/* 1516 * A S T P _ s a v e _ f i e l d _ r e f _ c o n t e x t 1517 * ===================================================== 1518 * 1519 * Saves the necessary information in a field reference 1520 * context block such that it can be processed at a 1521 * later time. 1522 * 1523 * Inputs: 1524 * name Nametable identifier specifying the reference name. 1525 * field_ref_addr The field reference address where the pointer to the 1526 * referenced parameter node goes when it is later defined. 1527 * Outputs: 1528 * None. 1529 * 1530 * Function value: 1531 * None. 1532 * 1533 */ 1534static void ASTP_save_field_ref_context 1535( 1536 NAMETABLE_id_t name, 1537 AST_field_ref_n_t *field_ref_addr, 1538 fe_info_t *fe_info 1539) 1540{ 1541 ASTP_field_ref_ctx_t *field_ref_ctx_ptr; 1542 1543 field_ref_ctx_ptr = NEW (ASTP_field_ref_ctx_t); 1544 field_ref_ctx_ptr->fe_info = fe_info; 1545 1546 /* Save context and link to context list */ 1547 field_ref_ctx_ptr->name = name; 1548 field_ref_ctx_ptr->field_ref_ptr = field_ref_addr; 1549 1550 ASTP_field_ref_ctx_list = (ASTP_field_ref_ctx_t *) 1551 AST_concat_element((ASTP_node_t *)ASTP_field_ref_ctx_list, 1552 (ASTP_node_t *)field_ref_ctx_ptr); 1553 1554 return; 1555} 1556 1557/*--------------------------------------------------------------------*/ 1558 1559/* 1560 * A S T _ s e t _ a r r a y _ r e p _ t y p e 1561 * ============================================ 1562 * 1563 * This routine should be called with pointer that has the [string] attribute. 1564 * It sets the array_rep_type of the type passed if it is pointer and it 1565 * doesn't yet have an array rep. 1566 */ 1567 1568void ASTP_set_array_rep_type 1569( 1570 parser_location_p location, 1571 AST_type_n_t *type_node_ptr, 1572 AST_type_n_t *array_base_type, 1573 boolean is_varying 1574) 1575{ 1576 char *identifier ATTRIBUTE_UNUSED; 1577 AST_type_p_n_t *tp_node ATTRIBUTE_UNUSED; /* type pointer node for interface's 1578 linked list of transmit_as types */ 1579 1580 /* If the type is pointer, and no array_rep_type then create one */ 1581 if (type_node_ptr->kind == AST_pointer_k) 1582 { 1583 if (type_node_ptr->type_structure.pointer->pointee_type->array_rep_type == NULL) 1584 { 1585 /* 1586 * No array node, so special processing, for pointers treated as 1587 * arrays. We now fill-in the array_rep_type field of the pointer node 1588 * to contain a conformant array node representing the pointer as if it 1589 * had been declared using array syntax. 1590 */ 1591 AST_type_n_t *array_rep_of_pointer; 1592 AST_array_n_t *array_node; 1593 1594 array_node = AST_array_node(location, array_base_type); 1595 array_node->index_count = 1; 1596 array_node->index_vec = AST_array_index_node(location, 1); 1597 array_node->index_vec->lower_bound = zero_constant_p; 1598 AST_SET_FIXED_LOWER(array_node->index_vec); 1599 1600 array_rep_of_pointer = AST_type_node(location, AST_array_k); 1601 array_rep_of_pointer->type_structure.array = array_node; 1602 AST_SET_CONFORMANT(array_rep_of_pointer); 1603 type_node_ptr->type_structure.pointer->pointee_type->array_rep_type = array_rep_of_pointer; 1604 1605 /* 1606 * Do the same processing on the original of a DEF_AS_TAG node. 1607 */ 1608 if (AST_DEF_AS_TAG_SET(type_node_ptr->type_structure.pointer->pointee_type) && 1609 (type_node_ptr->type_structure.pointer->pointee_type->fe_info->original != NULL) && 1610 (type_node_ptr->type_structure.pointer->pointee_type->fe_info->original->array_rep_type == NULL)) 1611 { 1612 ASTP_set_array_rep_type(location, type_node_ptr, 1613 type_node_ptr->type_structure.pointer->pointee_type->fe_info->original, 1614 is_varying); 1615 } 1616 } 1617 1618 /* 1619 * Set the varying flag on the type, if referenced as varying inorder 1620 * to indicate that the pointed at routine must be generated to 1621 * support varying instances. 1622 */ 1623 if (is_varying) 1624 { 1625 AST_SET_VARYING(type_node_ptr->type_structure.pointer->pointee_type->array_rep_type); 1626 1627 /* 1628 * Do the same processing on the original of a DEF_AS_TAG node. 1629 */ 1630 if (AST_DEF_AS_TAG_SET(type_node_ptr->type_structure.pointer->pointee_type) && 1631 (type_node_ptr->type_structure.pointer->pointee_type->fe_info->original != NULL) && 1632 (type_node_ptr->type_structure.pointer->pointee_type->fe_info->original->array_rep_type != NULL)) 1633 { 1634 AST_SET_VARYING(type_node_ptr->type_structure.pointer->pointee_type->fe_info->original->array_rep_type); 1635 } 1636 } 1637 } 1638} 1639 1640/*--------------------------------------------------------------------*/ 1641 1642/* 1643 * A S T _ l o o k u p _ f i e l d _ a t t r 1644 * 1645 * Returns TRUE if the specified field attribute appears in the specified 1646 * attribute list. 1647 */ 1648 1649boolean AST_lookup_field_attr 1650( 1651 ASTP_attributes_t *attributes, /* [in] Attributes - bounds field is */ 1652 /* linked list of field attrs */ 1653 ASTP_attr_k_t field_attr /* [in] Field attribute to look up */ 1654) 1655{ 1656 ASTP_type_attr_n_t *bound_p; 1657 1658 for (bound_p = attributes->bounds; bound_p != NULL; bound_p = bound_p->next) 1659 { 1660 if (bound_p->kind == field_attr) 1661 return TRUE; 1662 } 1663 1664 return FALSE; 1665} 1666 1667/*--------------------------------------------------------------------*/ 1668 1669/* 1670 * A S T _ s e t _ f i e l d _ a t t r s 1671 * ===================================== 1672 * 1673 * Set the field attributes of a parameter or structure. In addition, if type 1674 * is a pointer used as an array, the array_rep_type field of the pointer node 1675 * is filled in with a type node used to represent the array implicitly created 1676 * by using a pointer in this manner. 1677 * 1678 * Inputs: 1679 * attributes attr_flags = boolean attributes 1680 * array_bounds = a pointer to a linked list describing the field 1681 * attributes that were specified. 1682 * 1683 * parent_node Pointer to the parent node containing the 1684 * field attribute pointer. This is either 1685 * a pointer to a parameter node or field node. 1686 * For parameters, this is used to track down 1687 * the array node to get the array dimension. 1688 * Used to also access the fe_info to see determine 1689 * node it is, so we know whether we dealing with 1690 * a field or parameter attributes. 1691 * 1692 * type_node Pointer to the type node representing the 1693 * field or parameter type. 1694 * 1695 * Outputs: 1696 * None. 1697 * 1698 * Function Value: 1699 * Pointer to the field attribute node created. 1700 * 1701 */ 1702 1703AST_field_attr_n_t *AST_set_field_attrs 1704( 1705 parser_location_p location, 1706 ASTP_attributes_t *attributes, 1707 ASTP_node_t *parent_node, 1708 AST_type_n_t *type_node 1709) 1710{ 1711 AST_field_attr_n_t 1712 *field_attr_node; /* Pointer to field attribute node */ 1713 AST_field_ref_n_t 1714 *field_ref_vector = NULL; /* Pointer to the field_ref vector */ 1715 ASTP_type_attr_n_t 1716 *attr_ptr, /* Pointer to an element of array_bounds */ 1717 *next_attr_ptr; /* For loop - next attribute to process */ 1718 ASTP_node_t 1719 *referent_node; /* Pointer to node describing the reference 1720 specified as the array bound */ 1721 AST_type_n_t 1722 *clone_type ATTRIBUTE_UNUSED, /* For setting conformant flag for pointer types */ 1723 *tp; /* For loop to get to index_count */ 1724 unsigned short 1725 dimension = 0, /* number of dimensions for the array */ 1726 index_count; /* Used to catch mismatch in number of 1727 references specified and dimension */ 1728 boolean pointer_as_array = FALSE, 1729 noforward_ref = TRUE; /* Forward refs. allowed only for parameters */ 1730 ASTP_attr_k_t 1731 current_attr_kind; /* Current attribute being worked on */ 1732 boolean array_attr_valid = TRUE; /* Array attrs valid on this type */ 1733 boolean neu_attr_valid = FALSE; /* Nonencap union attrs valid on type */ 1734 1735 /* 1736 * If no bounds information, and not arrayified via [string], done 1737 */ 1738 if ((attributes->bounds == NULL) && !ASTP_TEST_ATTR(attributes,(ASTP_STRING))) 1739 return (AST_field_attr_n_t *)NULL; 1740 1741 /* 1742 * Assume that array attrs and switch attr are to be mutually exclusive 1743 * (because arrays of non-encapsulated unions are not yet allowed), so if 1744 * the type node is a pointer and the pointee type is a union with no 1745 * discriminator name, we can usually assume this is a reference to a non- 1746 * encapsulated union type, and only the switch attr is to be valid. 1747 * However if the union type is incomplete (thus the union node address is 1748 * not yet initialized), it follows that the pointer is a self-referential 1749 * pointer to a union type. This could be an arrayified encapsulated union 1750 * self-reference or a simple pointer to a non-encapsulated union self- 1751 * reference. Look at the attributes specified, and if switch_is is present, 1752 * assume the latter, otherwise, assume the former. This code will need work 1753 * if/when we support arrays of non-encapsulated unions. 1754 */ 1755 tp = ASTP_chase_ptr_to_kind(type_node, AST_disc_union_k); 1756 if (tp != NULL 1757 && ( (tp->type_structure.disc_union != NULL 1758 && tp->type_structure.disc_union->discrim_name == NAMETABLE_NIL_ID) 1759 || (FE_TEST(tp->fe_info->flags, FE_INCOMPLETE) 1760 && AST_lookup_field_attr(attributes, switch_is_k)) )) 1761 { 1762 dimension = 1; 1763 array_attr_valid = FALSE; 1764 neu_attr_valid = TRUE; 1765 } 1766 else 1767 { 1768 /* 1769 * Determine dimension of the array for 1770 * allocating field_reference vector. 1771 */ 1772 tp = ASTP_chase_ptr_to_kind(type_node, AST_array_k); 1773 1774 /* 1775 * If there is no array node, then verify that this type may be arrayified 1776 * via attributes. If not, issue an error. 1777 */ 1778 if (tp == NULL) 1779 { 1780 if (((parent_node->fe_info->node_kind == fe_field_n_k) && 1781 (type_node->kind != AST_pointer_k)) || 1782 ((parent_node->fe_info->node_kind == fe_parameter_n_k) && 1783 ((type_node->kind != AST_pointer_k)|| 1784 (type_node->name != NAMETABLE_NIL_ID)))) 1785 { 1786 /* 1787 * Output an error (except when only [string] attribute is present 1788 * because this is caught by checker) and return if we don't find 1789 * an array node or anonymous pointer hanging off of this type. 1790 */ 1791 if (attributes->bounds != NULL) 1792 { 1793 if (attributes->bounds->kind == range_k) 1794 { 1795 AST_exp_n_t *exp; 1796 1797 field_attr_node = AST_field_attr_node(location); 1798 field_attr_node->range = NEW(AST_tuple_n_t); 1799 1800 exp = attributes->bounds->b.expr; 1801 field_attr_node->range->value[0] = 1802 ASTP_expr_integer_value(location, exp->exp.expression.oper1); 1803 field_attr_node->range->value[1] = 1804 ASTP_expr_integer_value(location, exp->exp.expression.oper2); 1805 1806 if (field_attr_node->range->value[0] > field_attr_node->range->value[1]) 1807 log_error(location->lineno, NIDL_INVALIDRANGE, NULL); 1808 1809 return field_attr_node; 1810 } 1811 /* Base the error on the first invalid "bounds" attribute. */ 1812 else if (attributes->bounds->kind == switch_is_k) 1813 log_error(location->lineno, NIDL_SWATTRNEU, NULL); 1814 else 1815 log_error(location->lineno, NIDL_SIZEARRTYPE, NULL); 1816 } 1817 return (AST_field_attr_n_t *)NULL; 1818 } 1819 } 1820 1821 /* 1822 * We now know we either have an array or a top level pointer used an 1823 * array. If we found an array node, we can directly access it. 1824 */ 1825 if (tp != NULL) 1826 { 1827 dimension = tp->type_structure.array->index_count; 1828 } 1829 1830 /* If create the array_rep_type for this pointee */ 1831 else if (type_node->kind == AST_pointer_k) 1832 { 1833 tp = type_node; 1834 while(tp->type_structure.pointer->pointee_type->kind == AST_pointer_k && tp->kind != AST_interface_k) 1835 tp = tp->type_structure.pointer->pointee_type; 1836 1837 dimension = 1; 1838 pointer_as_array = TRUE; 1839 ASTP_set_array_rep_type(location, type_node, 1840 type_node->type_structure.pointer->pointee_type, 1841 FALSE); 1842 } 1843 1844 /* 1845 * If only arrayified via [string] then all we needed to do was fill in 1846 * the array_rep_type of the pointer which we have done, so return 1847 */ 1848 if (attributes->bounds == NULL) 1849 { 1850 ASTP_set_array_rep_type(location, type_node, 1851 type_node->type_structure.pointer->pointee_type, 1852 TRUE); 1853 return (AST_field_attr_n_t *)NULL; 1854 } 1855 } 1856 1857 /* Allocate and initialize field attribute node */ 1858 field_attr_node = AST_field_attr_node(location); 1859 1860 /* 1861 * A field attribute node points to a vector of 1862 * field reference nodes, one for each dimension, 1863 * and tells whether the node contains a valid 1864 * reference. If valid, it points to the field or 1865 * parameter node containing the attribute reference. 1866 * 1867 * Note, parameter references can be forwarded. (This 1868 * is not allowed for field references). 1869 * If the parameter is referenced before the formal parameter 1870 * definition, we save the context containing a the address 1871 * to place the reference pointer, and patch it up later on 1872 * when finishing up the operation. 1873 */ 1874 1875 /* 1876 * Loop through the array bound linked list creating the 1877 * field reference vector for each field attribute present. 1878 * An inner loop processes the field references for each 1879 * dimension of the same array bound type. 1880 */ 1881 1882 for (attr_ptr=attributes->bounds; 1883 attr_ptr != NULL; 1884 attr_ptr= attr_ptr->next) 1885 { 1886 if (attr_ptr->kind != switch_is_k && !array_attr_valid) 1887 { 1888 log_error(location->lineno, NIDL_SIZEARRTYPE, NULL); 1889 return (AST_field_attr_n_t *)NULL; 1890 } 1891 if (attr_ptr->kind == switch_is_k && !neu_attr_valid) 1892 { 1893 log_error(location->lineno, NIDL_SWATTRNEU, NULL); 1894 return (AST_field_attr_n_t *)NULL; 1895 } 1896 /* 1897 * Get (create if not yet specified) the field reference vector 1898 * for the attribute specified. 1899 */ 1900 switch (attr_ptr->kind) 1901 { 1902 case iid_is_k: 1903 if (field_attr_node->iid_is == NULL) 1904 { 1905 field_attr_node->iid_is = 1906 AST_field_ref_node(location, dimension); 1907 } 1908 field_ref_vector = field_attr_node->iid_is; 1909 break; 1910 case first_is_k: 1911 if (field_attr_node->first_is_vec == NULL) 1912 { 1913 field_attr_node->first_is_vec = 1914 AST_field_ref_node(location, dimension); 1915 } 1916 field_ref_vector = field_attr_node->first_is_vec; 1917 break; 1918 1919 case last_is_k: 1920 if (field_attr_node->last_is_vec == NULL) 1921 { 1922 field_attr_node->last_is_vec = 1923 AST_field_ref_node(location, dimension); 1924 } 1925 field_ref_vector = field_attr_node->last_is_vec; 1926 break; 1927 1928 case length_is_k: 1929 if (field_attr_node->length_is_vec == NULL) 1930 { 1931 field_attr_node->length_is_vec = 1932 AST_field_ref_node(location, dimension); 1933 } 1934 field_ref_vector = field_attr_node->length_is_vec; 1935 break; 1936 1937 case min_is_k: 1938 if (field_attr_node->min_is_vec == NULL) 1939 { 1940 field_attr_node->min_is_vec = 1941 AST_field_ref_node(location, dimension); 1942 } 1943 field_ref_vector = field_attr_node->min_is_vec; 1944 break; 1945 1946 case max_is_k: 1947 if (field_attr_node->max_is_vec == NULL) 1948 { 1949 field_attr_node->max_is_vec = 1950 AST_field_ref_node(location, dimension); 1951 } 1952 field_ref_vector = field_attr_node->max_is_vec; 1953 break; 1954 1955 case size_is_k: 1956 if (field_attr_node->size_is_vec == NULL) 1957 { 1958 field_attr_node->size_is_vec = 1959 AST_field_ref_node(location, dimension); 1960 } 1961 field_ref_vector = field_attr_node->size_is_vec; 1962 break; 1963 case switch_is_k: 1964 if (field_attr_node->switch_is == NULL) 1965 { 1966 field_attr_node->switch_is = 1967 AST_field_ref_node(location, 1); 1968 } 1969 field_ref_vector = field_attr_node->switch_is; 1970 break; 1971 1972 default: 1973 break; 1974 } 1975 1976 /* Set varying flag if last_is/length_is/first_is */ 1977 if ((attr_ptr->kind == last_is_k) || 1978 (attr_ptr->kind == length_is_k) || 1979 (attr_ptr->kind == first_is_k)) 1980 { 1981 if (parent_node->fe_info->node_kind == fe_parameter_n_k) 1982 { 1983 AST_SET_VARYING((AST_parameter_n_t*)parent_node); 1984 } 1985 else 1986 { 1987 AST_SET_VARYING((AST_field_n_t*)parent_node); 1988 } 1989 1990 if (pointer_as_array) 1991 { 1992 ASTP_set_array_rep_type(location, type_node, 1993 type_node->type_structure.pointer->pointee_type, 1994 TRUE); 1995 } 1996 } 1997 1998 /* Process all references specified for this attribute */ 1999 current_attr_kind = attr_ptr->kind; 2000 next_attr_ptr = attr_ptr; 2001 index_count = 0; 2002 do 2003 { 2004 assert(field_ref_vector != NULL); 2005 2006 if (index_count >= dimension) 2007 { 2008 log_error(location->lineno, NIDL_SIZEMISMATCH, NULL); 2009 break; 2010 } 2011 2012 /* Get next attribute reference */ 2013 attr_ptr = next_attr_ptr; 2014 2015 /* Proceed if reference name was specified */ 2016 if (attr_ptr->is_expr || attr_ptr->b.simple.name != NAMETABLE_NIL_ID) 2017 { 2018 AST_exp_n_t * exp = NULL; 2019 2020 /* 2021 * Set the pointer count. 2022 * (This will need to be a bit more 2023 * sophisicated IF/WHEN IDL supports full 2024 * declarators for array bound references.) 2025 */ 2026 if (attr_ptr->is_expr) 2027 { 2028 exp = attr_ptr->b.expr; 2029 /* 2030 * NB: extended simple expressions to handle multiple and 2031 * division by 4 and 8 to handle LOGON_HOURS. This should 2032 * be fixed properly as part of complex expression support. 2033 * 2034 * 03-04-10 lukeh 2035 */ 2036 if (ASTP_expr_is_simple(location, exp)) 2037 { 2038 /* chase the dereferences */ 2039 while(exp->exp_type == AST_EXP_UNARY_STAR) 2040 { 2041 field_ref_vector->fe_info->pointer_count++; 2042 exp = attr_ptr->b.expr = exp->exp.expression.oper1; 2043 } 2044 switch(exp->exp_type) 2045 { 2046 case AST_EXP_CONSTANT: 2047 break; 2048 case AST_EXP_BINARY_SLASH: 2049 switch (ASTP_expr_integer_value(location, exp->exp.expression.oper2)) 2050 { 2051 case 8: field_ref_vector->xtra_opcode = IR_EXP_FC_DIV_8; break; 2052 case 4: field_ref_vector->xtra_opcode = IR_EXP_FC_DIV_4; break; 2053 case 2: field_ref_vector->xtra_opcode = IR_EXP_FC_DIV_2; break; 2054 default: log_error(location->lineno, NIDL_ONLYSIMPLEEXP, NULL); return NULL; 2055 } 2056 exp = exp->exp.expression.oper1; 2057 break; 2058 case AST_EXP_BINARY_STAR: 2059 switch (ASTP_expr_integer_value(location, exp->exp.expression.oper2)) 2060 { 2061 case 8: field_ref_vector->xtra_opcode = IR_EXP_FC_MUL_8; break; 2062 case 4: field_ref_vector->xtra_opcode = IR_EXP_FC_MUL_4; break; 2063 case 2: field_ref_vector->xtra_opcode = IR_EXP_FC_MUL_2; break; 2064 default: log_error(location->lineno, NIDL_ONLYSIMPLEEXP, NULL); return NULL; 2065 } 2066 exp = exp->exp.expression.oper1; 2067 break; 2068 case AST_EXP_BINARY_PLUS: 2069 field_ref_vector->xtra_opcode = IR_EXP_FC_ADD_1; 2070 exp = exp->exp.expression.oper1; 2071 break; 2072 case AST_EXP_BINARY_MINUS: 2073 field_ref_vector->xtra_opcode = IR_EXP_FC_SUB_1; 2074 exp = exp->exp.expression.oper1; 2075 break; 2076 case AST_EXP_BINARY_AND: 2077 switch(ASTP_expr_integer_value(location, exp->exp.expression.oper1->exp.expression.oper2)) 2078 { 2079 case 1: 2080 field_ref_vector->xtra_opcode = IR_EXP_FC_ALIGN_2; 2081 break; 2082 case 3: 2083 field_ref_vector->xtra_opcode = IR_EXP_FC_ALIGN_4; 2084 break; 2085 case 7: 2086 field_ref_vector->xtra_opcode = IR_EXP_FC_ALIGN_4; 2087 break; 2088 } 2089 exp = exp->exp.expression.oper1->exp.expression.oper1; 2090 while(exp->exp_type == AST_EXP_UNARY_STAR) 2091 { 2092 field_ref_vector->fe_info->pointer_count++; 2093 exp = attr_ptr->b.expr = exp->exp.expression.oper1; 2094 } 2095 break; 2096 } 2097 if (exp->exp_type != AST_EXP_CONSTANT) 2098 { 2099 log_error(location->lineno, NIDL_ONLYSIMPLEEXP, NULL); 2100 return NULL; 2101 } 2102 else if (exp->exp.constant.type != AST_nil_const_k) 2103 { 2104 field_ref_vector->constant = true; 2105 field_ref_vector->ref.integer = 2106 ASTP_expr_integer_value(location, exp); 2107 } 2108 else 2109 { 2110 field_ref_vector->constant = false; 2111 } 2112 attr_ptr->is_expr = false; 2113 /* apply the EXP_CONSTANT details to the stuff below */ 2114 attr_ptr->b.simple.name = exp->exp.constant.name; 2115 } 2116 else 2117 { 2118 log_error(location->lineno, NIDL_ONLYSIMPLEEXP, NULL) ; 2119 return NULL; 2120 } 2121 } 2122 else if (attr_ptr->b.simple.pointer) 2123 { 2124 field_ref_vector->fe_info->pointer_count = 1; 2125 } 2126 2127 /* 2128 * Lookup binding, output error if invalid type, 2129 * but allow forward references for parameters and fields. 2130 */ 2131 if ((parent_node->fe_info->node_kind == fe_parameter_n_k) || 2132 (parent_node->fe_info->node_kind == fe_field_n_k)) 2133 { 2134 noforward_ref = FALSE; 2135 } 2136 2137 referent_node = (ASTP_node_t *) 2138 ASTP_lookup_binding(location, attr_ptr->b.simple.name, 2139 parent_node->fe_info->node_kind, 2140 noforward_ref); 2141 /* 2142 * Set valid bit and fill in reference pointer 2143 * if lookup succeeded. 2144 */ 2145 if (referent_node != NULL) 2146 { 2147 field_ref_vector->valid = TRUE; 2148 2149 if (parent_node->fe_info->node_kind == fe_parameter_n_k) 2150 { 2151 field_ref_vector->ref.p_ref = 2152 (AST_parameter_n_t *)referent_node; 2153 } 2154 else 2155 { 2156 field_ref_vector->ref.f_ref = 2157 (AST_field_n_t *)referent_node; 2158 } 2159 } 2160 else if (field_ref_vector->constant == true) 2161 { 2162 field_ref_vector->valid = true; 2163 } 2164 else 2165 { 2166 /* 2167 * If name binding is unknown, save context if 2168 * we're dealing with parameters or fields, otherwise 2169 * output an error. 2170 */ 2171 if ((parent_node->fe_info->node_kind == fe_parameter_n_k) || 2172 (parent_node->fe_info->node_kind == fe_field_n_k)) 2173 { 2174 /* Name not bound yet, save context for later */ 2175 ASTP_save_field_ref_context( 2176 attr_ptr->b.simple.name, 2177 field_ref_vector, 2178 parent_node->fe_info); 2179 } 2180 else 2181 { 2182 char const *identifier; 2183 NAMETABLE_id_to_string (attr_ptr->b.simple.name, 2184 &identifier); 2185 log_error(location->lineno, NIDL_NAMENOTFND, identifier, NULL) ; 2186 } 2187 } 2188 } 2189 2190 /* 2191 * Point to next array bound element 2192 * and reference vector element. 2193 */ 2194 next_attr_ptr = next_attr_ptr->next; 2195 field_ref_vector++; 2196 index_count++; 2197 } 2198 while ( (attr_ptr->next != NULL) && 2199 (attr_ptr->next->kind == current_attr_kind)) ; 2200 2201 } /* end for processing all attributes in attributes->bounds */ 2202 2203 return field_attr_node; 2204 2205} 2206 2207/*--------------------------------------------------------------------*/ 2208 2209/* 2210 * A S T _ s e t _ t y p e _ a t t r s 2211 * =================================== 2212 * 2213 * Merge the boolean and non-boolean attributes 2214 * to the type node. 2215 */ 2216 2217AST_type_n_t *AST_set_type_attrs 2218( 2219 parser_location_p location, 2220 AST_type_n_t *type_node_ptr, 2221 ASTP_attributes_t *attributes 2222) 2223{ 2224 AST_type_p_n_t *tp_node; /* type pointer node for interface's 2225 linked list of transmit_as types */ 2226 2227 /* Propagate the boolean attributes to the type node */ 2228 AST_set_flags(location, &type_node_ptr->flags,(ASTP_node_t *)type_node_ptr, attributes); 2229 2230 /* if this is a [v1_enum] enum make it be a long at NDR level */ 2231 if (AST_V1_ENUM_SET(type_node_ptr)) 2232 { 2233 type_node_ptr->ndr_size = 4; 2234 type_node_ptr->alignment_size = type_node_ptr->ndr_size; 2235 } 2236 2237 /* If [string] on a pointer type and no array_rep_type then create one */ 2238 if (ASTP_TEST_ATTR(attributes,(ASTP_STRING)) && 2239 (type_node_ptr->kind == AST_pointer_k)) 2240 { 2241 ASTP_set_array_rep_type(location, type_node_ptr, 2242 type_node_ptr->type_structure.pointer->pointee_type, 2243 TRUE); 2244 } 2245 2246 /* Check the transmit_as attribute */ 2247 if (ASTP_TEST_ATTR(attributes,ASTP_TRANSMIT_AS)) 2248 { 2249 type_node_ptr->xmit_as_type = ASTP_transmit_as_type; 2250 if (type_node_ptr->xmit_as_type == NULL) 2251 INTERNAL_ERROR("ASTP_transmit_as_type is NULL when attribute set"); 2252 } 2253 /* Check the switch_type attribute */ 2254 if (ASTP_TEST_ATTR(attributes,ASTP_SWITCH_TYPE)) 2255 { 2256 if (type_node_ptr->kind != AST_disc_union_k) 2257 log_error(location->lineno, NIDL_SWTYPENEU, NULL); /* non-union type */ 2258 else if (type_node_ptr->type_structure.disc_union == NULL) 2259 ASTP_validate_forward_ref(location, type_node_ptr); /* incomplete type */ 2260 else if (type_node_ptr->type_structure.disc_union->discrim_name 2261 != NAMETABLE_NIL_ID) /* encap union type */ 2262 log_error(location->lineno, NIDL_SWTYPENEU, NULL); 2263 else 2264 { 2265 type_node_ptr->type_structure.disc_union->discrim_type 2266 = ASTP_switch_type; 2267 if (ASTP_switch_type == NULL) 2268 INTERNAL_ERROR("ASTP_switch_type is NULL when attribute set"); 2269 } 2270 } 2271 2272 /* Check for pipe type and link onto pipe_types list */ 2273 if (type_node_ptr->kind == AST_pipe_k) 2274 { 2275 /* 2276 * Create a new type pointer node and link the pipe type on to 2277 * pipe_types list to be later put on the interface node 2278 */ 2279 tp_node = AST_type_ptr_node(location); 2280 tp_node->type = type_node_ptr; 2281 2282 the_interface->pipe_types = (AST_type_p_n_t *) 2283 AST_concat_element((ASTP_node_t *)the_interface->pipe_types, 2284 (ASTP_node_t *)tp_node); 2285 } 2286 2287 return type_node_ptr; 2288} 2289 2290/*---------------------------------------------------------------------*/ 2291 2292/* 2293 * A S T P _ f r e e _ d e c l a r a t o r s 2294 * ========================================== 2295 * 2296 * Loop through the specified list of declarators and free 2297 * them and any indices that are hanging off of the 2298 * declarators. 2299 * 2300 */ 2301 2302void ASTP_free_declarators 2303( 2304 ASTP_declarator_n_t *declarators_ptr 2305) 2306{ 2307 ASTP_declarator_n_t 2308 *dp, /* For traversing through declarators */ 2309 *next_dp; 2310 2311 ASTP_declarator_op_n_t 2312 *dop, /* For traversing through declarators */ 2313 *next_dop; 2314 2315 ASTP_array_index_n_t 2316 *index_node, /* For freeing array index nodes */ 2317 *next_index; /* "" */ 2318 2319 /* Free temporary declarators list */ 2320 for (dp = declarators_ptr, next_dp = declarators_ptr; 2321 next_dp != (ASTP_declarator_n_t *) NULL; 2322 dp= next_dp) 2323 { 2324 next_dp = dp->next; /* Save next link before freeing */ 2325 2326 /* Free declarator operations linked list */ 2327 for (dop = dp->next_op, next_dop = dp->next_op; 2328 next_dop != NULL; 2329 dop = next_dop) 2330 { 2331 /* Free array indices linked list in this declarator op, if any */ 2332 if (dop->op_kind == AST_array_k) 2333 { 2334 for (index_node = dop->op_info.indices, next_index = dop->op_info.indices; 2335 next_index != NULL; 2336 index_node = next_index) 2337 { 2338 next_index = index_node->next; 2339 FREE(index_node); 2340 } 2341 } 2342 2343 next_dop = dop->next_op; 2344 FREE(dop); 2345 } 2346 2347 FREE(dp); 2348 } 2349 2350 return; 2351} 2352 2353/*-----------------------------------------------------------------------*/ 2354 2355/* 2356 * A S T P _ f r e e _ s i m p l e _ l i s t 2357 * ========================================= 2358 * 2359 * Loop through a list of simple elements, i.e. 2360 * no allocated lists hanging off the list element. 2361 * 2362 */ 2363 2364void ASTP_free_simple_list 2365( 2366 ASTP_node_t *list_ptr 2367) 2368{ 2369 ASTP_node_t *lp, 2370 *next_lp; 2371 2372 for (lp = list_ptr, next_lp = list_ptr; 2373 next_lp != (ASTP_node_t *) NULL; 2374 lp = next_lp) 2375 { 2376 next_lp = lp->next; 2377 FREE(lp); 2378 } 2379 2380 return; 2381} 2382 2383/*-----------------------------------------------------------------------*/ 2384 2385/* 2386 * A S T P _ p a t c h _ f i e l d _ r e f e r e n c e 2387 * =================================================== 2388 * 2389 * Patches the field reference node parameter node address 2390 * which at the time the field attribute was parsed, 2391 * a binding of a parameter type was not yet defined. 2392 * 2393 * Inputs: 2394 * None. 2395 * 2396 * Outputs: 2397 * None. 2398 * 2399 * Function value: 2400 * None. 2401 * 2402 */ 2403void ASTP_patch_field_reference 2404( 2405 parser_location_p location 2406) 2407{ 2408 ASTP_field_ref_ctx_t *field_ref_ctx; 2409 AST_parameter_n_t *parameter_node_ptr; 2410 AST_field_n_t *field_node_ptr; 2411 2412 for (field_ref_ctx = ASTP_field_ref_ctx_list; 2413 field_ref_ctx != NULL; 2414 field_ref_ctx = field_ref_ctx->next) 2415 { 2416 /* Processing for parameter references */ 2417 if (field_ref_ctx->fe_info->node_kind == fe_parameter_n_k) 2418 { 2419 /* Lookup binding and output error if not found or invalid type */ 2420 parameter_node_ptr = (AST_parameter_n_t *) 2421 ASTP_lookup_binding(location, field_ref_ctx->name, 2422 fe_parameter_n_k, TRUE); 2423 if (parameter_node_ptr != NULL) 2424 { 2425 field_ref_ctx->field_ref_ptr->ref.p_ref = parameter_node_ptr; 2426 field_ref_ctx->field_ref_ptr->valid = TRUE; 2427 } 2428 } 2429 2430 /* Processing for field references */ 2431 if (field_ref_ctx->fe_info->node_kind == fe_field_n_k) 2432 { 2433 /* Lookup binding and output error if not found or invalid type */ 2434 field_node_ptr = (AST_field_n_t *) 2435 ASTP_lookup_binding(location, field_ref_ctx->name, 2436 fe_field_n_k, TRUE); 2437 if (field_node_ptr != NULL) 2438 { 2439 field_ref_ctx->field_ref_ptr->ref.f_ref = field_node_ptr; 2440 field_ref_ctx->field_ref_ptr->valid = TRUE; 2441 } 2442 } 2443 } 2444 2445 ASTP_field_ref_ctx_list = NULL; /* NULL listhead */ 2446 2447 return; 2448} 2449 2450/*---------------------------------------------------------------------*/ 2451 2452/* 2453 * A S T P _ s e t _ f e _ i n f o 2454 * =============================== 2455 * 2456 * Allocate and initialize a fe_info node and link it 2457 * into the fe_info field of the specified node. The 2458 * be_info field is set to NULL. 2459 * 2460 * Inputs: 2461 * node_ptr -- node to have the fe_info and be_info set 2462 * fe_node_kind -- type of fe_node to create 2463 */ 2464void ASTP_set_fe_info 2465( 2466 parser_location_p location, 2467 fe_info_t **fe_info_ptr, 2468 fe_node_k_t fe_node_kind 2469) 2470{ 2471 fe_info_t *fe_info; 2472 2473 fe_info = *fe_info_ptr = BE_ctx_malloc(sizeof (fe_info_t)); 2474 2475 fe_info->source_line = location->lineno; 2476 fe_info->file = location->fileid; 2477 fe_info->acf_source_line = 0; 2478 fe_info->acf_file = 0; 2479 fe_info->node_kind = fe_node_kind; 2480 fe_info->fe_type_id = fe_source_only; 2481 fe_info->tag_ptr = NULL; 2482 fe_info->tag_name = NAMETABLE_NIL_ID; 2483 fe_info->gen_index = 0; 2484 fe_info->pointer_count = 0; 2485 fe_info->flags = 0; 2486 fe_info->original = NULL; 2487} 2488 2489/*---------------------------------------------------------------------*/ 2490 2491/* 2492 * A S T P _ s a v e _ t a g _ r e f 2493 * ================================= 2494 * 2495 * Allocate and initialize a tag reference node and link it 2496 * into the ASTP_tag_ref_list to be processed at a later 2497 * time. 2498 * 2499 * Inputs: 2500 * node_ptr -- node to have the fe_info and be_info set 2501 * fe_node_kind -- type of fe_node to create 2502 */ 2503 2504void ASTP_save_tag_ref 2505( 2506 NAMETABLE_id_t identifier, 2507 AST_type_k_t kind, 2508 AST_type_n_t *type_node_ptr 2509) 2510{ 2511 ASTP_tag_ref_n_t *tag_ref_node_ptr; /* Tag reference node */ 2512 2513 /* 2514 * Make sure the type node specified could be a forward reference 2515 */ 2516 if ((type_node_ptr->kind != AST_structure_k) && 2517 (type_node_ptr->kind != AST_disc_union_k)) return; 2518 2519 /* 2520 * Then build a tag ref node and add to the list to be processed later to 2521 * fill in the structure information in the type node when it becomes 2522 * known. 2523 */ 2524 tag_ref_node_ptr = NEW (ASTP_tag_ref_n_t); 2525 tag_ref_node_ptr->ref_kind = kind; 2526 tag_ref_node_ptr->name = identifier; 2527 tag_ref_node_ptr->type_node_ptr = type_node_ptr; 2528 ASTP_tag_ref_list = (ASTP_tag_ref_n_t *) 2529 AST_concat_element((ASTP_node_t *)ASTP_tag_ref_list, 2530 (ASTP_node_t *)tag_ref_node_ptr); 2531 2532 /* 2533 * Mark the specified type node as incomplete 2534 */ 2535 FE_SET(type_node_ptr->fe_info->flags,FE_INCOMPLETE); 2536} 2537 2538/*---------------------------------------------------------------------*/ 2539 2540/* 2541 * A S T P _ p r o c e s s _ c o n t e x t _ t y p e 2542 * ================================================= 2543 * 2544 * This routine provides the processing needed for types that have 2545 * context_handle attribute. If not already marked with the 2546 * [context_handle] it is added to the ASTP_context_handle_types_list 2547 * 2548 * Inputs: 2549 * type_node_ptr -- The newly found context_handle type. 2550 */ 2551 2552static void ASTP_process_context_type 2553( 2554 AST_type_n_t *type_node_ptr 2555) 2556{ 2557 AST_SET_CONTEXT_RD(type_node_ptr); 2558} 2559 2560/*---------------------------------------------------------------------*/ 2561 2562/* 2563 * A S T _ s e t _ f l a g s 2564 * ======================================= 2565 * 2566 * This routine accepts a node and the vector of flag bits from 2567 * the grammar. It verifies the the attributes are valid in this 2568 * context, issues errors for those that are not, and then sets 2569 * the bits in the flags word specified. 2570 * 2571 * Inputs: 2572 * field_node_ptr -- node on which to set attributes 2573 * flags -- address of flags structure 2574 */ 2575 2576void AST_set_flags 2577( 2578 parser_location_p location, 2579 AST_flags_t *flags, 2580 ASTP_node_t *node_ptr, 2581 ASTP_attributes_t *attributes 2582) 2583{ 2584#define COPY_IF_LARGER(a,b) {if ((b) > (a)) (a) = (b);} 2585 ASTP_type_attr_n_t *bp; /* pointer to loop through bounds */ 2586 ASTP_attr_flag_t current_attribute; 2587 ASTP_attr_flag_t valid_attr_flags; 2588 long message_number = 0; 2589 boolean bounds_illegal = TRUE; 2590 2591 /* 2592 * Determine which flags are valid for this node type 2593 */ 2594 switch (node_ptr->fe_info->node_kind) 2595 { 2596 case fe_field_n_k: 2597 valid_attr_flags = ASTP_FIELD_FLAGS; 2598 message_number = NIDL_ILLFIELDATTR; 2599 bounds_illegal = FALSE; 2600 break; 2601 case fe_arm_n_k: 2602 valid_attr_flags = ASTP_ARM_FLAGS; 2603 message_number = NIDL_ILLMEMATTR; 2604 break; 2605 case fe_type_n_k: 2606 valid_attr_flags = ASTP_TYPE_FLAGS; 2607 message_number = NIDL_ILLTYPEATTR; 2608 break; 2609 case fe_parameter_n_k: 2610 valid_attr_flags = ASTP_PARAMETER_FLAGS; 2611 message_number = NIDL_ILLPARAMATTR; 2612 bounds_illegal = FALSE; 2613 break; 2614 case fe_operation_n_k: 2615 valid_attr_flags = ASTP_OPERATION_FLAGS; 2616 message_number = NIDL_ILLOPATTR; 2617 break; 2618 case fe_interface_n_k: 2619 valid_attr_flags = 0; 2620 message_number = NIDL_ILLINTATTR; 2621 break; 2622 default: 2623 valid_attr_flags = 0; 2624 break; 2625 } 2626 2627 /* 2628 * Loop through all possible attributes and either set the 2629 * attribute on the target node, or issue a message that it 2630 * is not valid on this node type. 2631 */ 2632 for (current_attribute = 1; /* start with first bit */ 2633 current_attribute != 0 && current_attribute <= (unsigned) ASTP_MAX_ATTRIBUTE; /* until and including last bit */ 2634 current_attribute <<= 1) /* Next higher bit */ 2635 { 2636 /* Check if the attribute flag is set */ 2637 if (ASTP_TEST_ATTR(attributes,current_attribute)) 2638 { 2639 /* Yes, so make sure it is valid on this node type before setting */ 2640 if ((current_attribute & ~valid_attr_flags) == 0) 2641 { 2642 switch (current_attribute) 2643 { 2644 /* With BROADCAST, IDEMPOTENT is implicit */ 2645 case ASTP_BROADCAST: 2646 *flags |= (AST_BROADCAST | AST_IDEMPOTENT); break; 2647 2648 /* MAYBE implies IDEMPOTENT */ 2649 case ASTP_MAYBE: 2650 *flags |= (AST_MAYBE | AST_IDEMPOTENT); break; 2651 2652 case ASTP_IDEMPOTENT: 2653 *flags |= AST_IDEMPOTENT; break; 2654 2655 case ASTP_REFLECT_DELETIONS: 2656 *flags |= AST_REFLECT_DELETIONS; break; 2657 2658 case ASTP_LOCAL: 2659 *flags |= AST_LOCAL; break; 2660 2661 case ASTP_IN: 2662 *flags |= AST_IN; break; 2663 2664 case ASTP_IN_SHAPE: 2665 *flags |= AST_IN_SHAPE; break; 2666 2667 case ASTP_OUT: 2668 *flags |= AST_OUT; break; 2669 2670 case ASTP_OUT_SHAPE: 2671 *flags |= AST_OUT_SHAPE; break; 2672 2673 case ASTP_STRING: 2674 *flags |= AST_STRING; break; 2675 2676 case ASTP_STRING0: 2677 *flags |= AST_STRING0; break; 2678 2679 case ASTP_UNIQUE: 2680 *flags |= AST_UNIQUE; break; 2681 2682 case ASTP_REF: 2683 *flags |= AST_REF; break; 2684 2685 case ASTP_PTR: 2686 *flags |= AST_PTR; break; 2687 2688 case ASTP_V1_ENUM: 2689 *flags |= AST_V1_ENUM; break; 2690 2691 case ASTP_IGNORE: 2692 *flags |= AST_IGNORE; break; 2693 2694 case ASTP_SMALL: 2695 *flags |= AST_SMALL; break; 2696 2697 case ASTP_HANDLE: 2698 *flags |= AST_HANDLE; break; 2699 2700 case ASTP_UNALIGN: 2701 *flags |= AST_UNALIGN; break; 2702 2703 case ASTP_ALIGN_SMALL: 2704 case ASTP_ALIGN_SHORT: 2705 case ASTP_ALIGN_LONG: 2706 case ASTP_ALIGN_HYPER: 2707 { 2708 log_error(location->lineno, NIDL_NYSALIGN, NULL); 2709#if 0 2710 AST_type_n_t *type_node_ptr = (AST_type_n_t *)node_ptr; 2711 2712 /* Set alignment requirement on type */ 2713 switch (current_attribute) 2714 { 2715 case ASTP_ALIGN_SMALL: 2716 COPY_IF_LARGER(type_node_ptr->alignment_size, NDR_C_SMALL_INT_SIZE) 2717 break; 2718 case ASTP_ALIGN_SHORT: 2719 COPY_IF_LARGER(type_node_ptr->alignment_size, NDR_C_SHORT_INT_SIZE) 2720 break; 2721 case ASTP_ALIGN_LONG: 2722 COPY_IF_LARGER(type_node_ptr->alignment_size, NDR_C_LONG_INT_SIZE) 2723 break; 2724 case ASTP_ALIGN_HYPER: 2725 COPY_IF_LARGER(type_node_ptr->alignment_size, NDR_C_HYPER_INT_SIZE) 2726 break; 2727 } 2728 2729 /* Disallow align on anything by arrays of bytes */ 2730 if (!((node_ptr->fe_info->node_kind == fe_type_n_k) && 2731 (type_node_ptr->kind == AST_array_k) && 2732 (type_node_ptr->type_structure.array != NULL) && 2733 (type_node_ptr->type_structure.array->index_count == 1) && 2734 (type_node_ptr->type_structure.array->element_type->kind == AST_byte_k))) 2735 { 2736 log_error(location->lineno, NIDL_ALIGNBYTEARRAY, NULL); 2737 } 2738#endif 2739 break; 2740 } 2741 2742 /* process type node with [context_handle] attribute */ 2743 case ASTP_CONTEXT: 2744 { 2745 if (node_ptr->fe_info->node_kind == fe_type_n_k) 2746 ASTP_process_context_type((AST_type_n_t *)node_ptr); 2747 else 2748 *flags |= AST_CONTEXT; 2749 break; 2750 } 2751 2752 /* Transmit_as handled in AST_set_type_attrs */ 2753 case ASTP_TRANSMIT_AS: 2754 break; 2755 /* switch_type handled in AST_set_type_attrs */ 2756 case ASTP_SWITCH_TYPE: 2757 break; 2758 /* range handled in AST_set_type_attrs */ 2759 case ASTP_RANGE: 2760 break; 2761 2762 /* Attribute has not been handled, bug */ 2763 default: 2764 error(NIDL_INTERNAL_ERROR, __FILE__, __LINE__); 2765 } 2766 } 2767 else 2768 { 2769 /* 2770 * It is not valid on this node type, so issue an error message 2771 */ 2772 log_error(location->lineno, message_number, 2773 KEYWORDS_lookup_text(AST_attribute_to_token(¤t_attribute)), NULL); 2774 } 2775 } 2776 } 2777 2778 /* 2779 * Issue errors on the bounds attributes if the are illegal here 2780 */ 2781 if (bounds_illegal) 2782 for (bp = attributes->bounds; bp; bp = bp->next) 2783 { 2784 long token = 0; 2785 switch (bp->kind) 2786 { 2787 case last_is_k: token = LAST_IS_KW; break; 2788 case first_is_k: token = FIRST_IS_KW; break; 2789 case max_is_k: token = MAX_IS_KW; break; 2790 case length_is_k: token = LENGTH_IS_KW; break; 2791 case size_is_k: token = SIZE_IS_KW; break; 2792 case switch_is_k: token = SWITCH_IS_KW; break; 2793 case min_is_k: token = MIN_IS_KW; break; 2794 case iid_is_k: token = IID_IS_KW; break; 2795 case range_k: token = RANGE_KW; break; 2796 } 2797 log_error(location->lineno, message_number, KEYWORDS_lookup_text(token), NULL) ; 2798 } 2799} 2800 2801/*---------------------------------------------------------------------*/ 2802 2803/* 2804 * A S T _ a t t r i b u t e _ t o _ t o k e n 2805 * =========================================== 2806 * 2807 * This routine accepts an attribute value and 2808 * returns it's token number. 2809 * 2810 * Inputs: 2811 * attribute -- Attribute to return the text of 2812 * 2813 * Returns: 2814 * long -- token number for the specified attribute 2815 */ 2816 2817long AST_attribute_to_token 2818( 2819 ASTP_attr_flag_t *attribute 2820) 2821{ 2822 switch (*attribute) 2823 { 2824 case ASTP_ALIGN_SMALL: return ALIGN_KW; 2825 case ASTP_ALIGN_SHORT: return ALIGN_KW; 2826 case ASTP_ALIGN_LONG: return ALIGN_KW; 2827 case ASTP_ALIGN_HYPER: return ALIGN_KW; 2828 case ASTP_BROADCAST: return BROADCAST_KW; 2829 case ASTP_MAYBE: return MAYBE_KW; 2830 case ASTP_IDEMPOTENT: return IDEMPOTENT_KW; 2831 case ASTP_REFLECT_DELETIONS: return REFLECT_DELETIONS_KW; 2832 case ASTP_IN: return IN_KW; 2833 case ASTP_OUT: return OUT_KW; 2834 case ASTP_STRING: return STRING_KW; 2835 case ASTP_STRING0: return V1_STRING_KW; 2836 case ASTP_IN_SHAPE: return IN_KW; 2837 case ASTP_OUT_SHAPE: return OUT_KW; 2838 case ASTP_UNIQUE: return UNIQUE_KW; 2839 case ASTP_PTR: return PTR_KW; 2840 case ASTP_REF: return REF_KW; 2841 case ASTP_IGNORE: return IGNORE_KW; 2842 case ASTP_SMALL: return V1_ARRAY_KW; 2843 case ASTP_HANDLE: return HANDLE_KW; 2844 case ASTP_CONTEXT: return CONTEXT_HANDLE_KW; 2845 case ASTP_TRANSMIT_AS: return TRANSMIT_AS_KW; 2846 case ASTP_UNALIGN: return V1_STRUCT_KW; 2847 case ASTP_V1_ENUM: return V1_ENUM_KW; 2848 case ASTP_CASE: return CASE_KW; 2849 case ASTP_DEFAULT: return DEFAULT_KW; 2850 case ASTP_SWITCH_TYPE: return SWITCH_TYPE_KW; 2851 default: return 0; 2852 } 2853} 2854 2855/*---------------------------------------------------------------------*/ 2856 2857/* 2858 * A S T _ g e n e r a t e _ n a m e 2859 * =========================================== 2860 * 2861 * This routine generates a name from the 2862 * the unique id stored in the interface 2863 * node and specified suffix. The name contains 2864 * the interface name and version plus a unique 2865 * integer. 2866 * 2867 * Inputs: 2868 * int_p -- interface node 2869 * suffix -- char * to be appended to generated name 2870 * 2871 * Returns: 2872 * NAMETABLE_id_t -- name table entry for generated name 2873 */ 2874 2875NAMETABLE_id_t AST_generate_name 2876( 2877 AST_interface_n_t *int_p, 2878 const char *suffix 2879) 2880{ 2881 char gen_name[MAX_ID+1]; /* Buffer for generated tag name */ 2882 char const *int_name; /* Interface name */ 2883 2884 /* retrieve the interface name */ 2885 NAMETABLE_id_to_string(int_p->name, &int_name); 2886 sprintf(gen_name, "%s_v%ld_%ld_%ld%s", int_name, int_p->version%65536, 2887 int_p->version/65536, int_p->fe_info->gen_index++,suffix); 2888 2889 if (strlen(gen_name) > MAX_ID) 2890 message_print(NIDL_NAMETOOLONG, nidl_yylineno); 2891 2892 return NAMETABLE_add_id(gen_name); 2893} 2894 2895/*---------------------------------------------------------------------*/ 2896 2897/* 2898 * A S T P _ v a l i d a t e _ i n t e g e r 2899 * =========================================== 2900 * 2901 * This routine accepts an ASTP expression struct 2902 * and coerces it into an integer for use in an 2903 * integer constant expression. If this is not possible, 2904 * and error results. 2905 * 2906 */ 2907 2908void ASTP_validate_integer 2909( 2910 parser_location_p location, 2911 AST_exp_n_t *exp_node 2912) 2913{ 2914 2915 if (!ASTP_evaluate_expr(location, exp_node, true)) { 2916 log_error(location->lineno, NIDL_NONINTEXP, NULL); 2917 return; 2918 } 2919 2920 /* 2921 * If not already a long, then must be a constant node, so attempt to 2922 * coerce it to an int. 2923 */ 2924 if (exp_node->exp.constant.type != AST_int_const_k) 2925 { 2926 switch (exp_node->exp.constant.val.other->kind) 2927 { 2928 case AST_int_const_k: 2929 exp_node->exp.constant.type = AST_int_const_k; 2930 exp_node->exp.constant.val.integer = exp_node->exp.constant.val.other->value.int_val; 2931 break; 2932 case AST_char_const_k: 2933 exp_node->exp.constant.type = AST_int_const_k; 2934 exp_node->exp.constant.val.integer = exp_node->exp.constant.val.other->value.char_val; 2935 break; 2936 default: 2937 exp_node->exp.constant.type = AST_int_const_k; 2938 exp_node->exp.constant.val.integer = 0; 2939 log_error(location->lineno,NIDL_NONINTEXP, NULL); 2940 break; 2941 } 2942 } 2943} 2944/*---------------------------------------------------------------------*/ 2945 2946/* 2947 * A S T P _ v e r i f y _ n o n _ a n o n y m o u s 2948 * ================================================= 2949 * 2950 * This routine accepts a type and verifies that 2951 * it may be pointed-at without the problems of 2952 * anonymous structures/unions not being compatible with 2953 * similarly defined structures/unions. 2954 * 2955 */ 2956 2957static void ASTP_verify_non_anonymous 2958( 2959 parser_location_p location, 2960 AST_type_n_t *type, 2961 ASTP_declarator_n_t *declarator_ptr 2962) 2963{ 2964 /* 2965 * Check that the base type is not an anonymous struct/union (has no name 2966 * and no tag name) 2967 */ 2968 if (!AST_DEF_AS_TAG_SET(type) && 2969 (type->name == NAMETABLE_NIL_ID) && 2970 (((type->kind == AST_disc_union_k) && 2971 (type->type_structure.disc_union != NULL) && 2972 (type->type_structure.disc_union->tag_name == NAMETABLE_NIL_ID)) 2973 || 2974 ((type->kind == AST_structure_k) && 2975 (type->type_structure.structure != NULL) && 2976 (type->type_structure.structure->tag_name == NAMETABLE_NIL_ID)))) 2977 { 2978 char const *identifier; 2979 NAMETABLE_id_to_string(declarator_ptr->name, &identifier); 2980 log_warning(location->lineno, NIDL_ANONTYPE, identifier, NULL); 2981 } 2982 2983} 2984 2985void ASTP_set_implicit_handle( 2986 AST_interface_n_t *int_p, 2987 NAMETABLE_id_t type_name, 2988 NAMETABLE_id_t handle_name 2989 ) 2990{ 2991 if (type_name != NAMETABLE_NIL_ID) { 2992 AST_type_n_t * type_p; 2993 2994 type_p = (AST_type_n_t*)NAMETABLE_lookup_binding(type_name); 2995 if (type_p != NULL && type_p->fe_info->node_kind == fe_type_n_k) 2996 { 2997 int_p->implicit_handle_name = handle_name; 2998 int_p->implicit_handle_type = type_p; 2999 int_p->implicit_handle_type_name = type_p->name; 3000 if (AST_HANDLE_SET(type_p)) 3001 AST_SET_IMPLICIT_HANDLE_G(int_p); 3002 } 3003 else { 3004 /* A user-defined type not defined in IDL */ 3005 int_p->implicit_handle_type_name = type_name; 3006 int_p->implicit_handle_type = NULL; 3007 int_p->implicit_handle_name = handle_name; 3008 AST_SET_IMPLICIT_HANDLE_G(int_p); 3009 } 3010 } 3011 else { 3012 int_p->implicit_handle_name = handle_name; 3013 int_p->implicit_handle_type = ASTP_handle_ptr; 3014 } 3015} 3016 3017/*---------------------------------------------------------------------*/ 3018/* preserve coding style vim: set tw=78 sw=3 ts=3: */ 3019