1 /* Implementation of Fortran 2003 Polymorphism. 2 Copyright (C) 2009-2020 Free Software Foundation, Inc. 3 Contributed by Paul Richard Thomas <pault@gcc.gnu.org> 4 and Janus Weil <janus@gcc.gnu.org> 5 6 This file is part of GCC. 7 8 GCC is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free 10 Software Foundation; either version 3, or (at your option) any later 11 version. 12 13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14 WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with GCC; see the file COPYING3. If not see 20 <http://www.gnu.org/licenses/>. */ 21 22 23 /* class.c -- This file contains the front end functions needed to service 24 the implementation of Fortran 2003 polymorphism and other 25 object-oriented features. */ 26 27 28 /* Outline of the internal representation: 29 30 Each CLASS variable is encapsulated by a class container, which is a 31 structure with two fields: 32 * _data: A pointer to the actual data of the variable. This field has the 33 declared type of the class variable and its attributes 34 (pointer/allocatable/dimension/...). 35 * _vptr: A pointer to the vtable entry (see below) of the dynamic type. 36 37 Only for unlimited polymorphic classes: 38 * _len: An integer(C_SIZE_T) to store the string length when the unlimited 39 polymorphic pointer is used to point to a char array. The '_len' 40 component will be zero when no character array is stored in 41 '_data'. 42 43 For each derived type we set up a "vtable" entry, i.e. a structure with the 44 following fields: 45 * _hash: A hash value serving as a unique identifier for this type. 46 * _size: The size in bytes of the derived type. 47 * _extends: A pointer to the vtable entry of the parent derived type. 48 * _def_init: A pointer to a default initialized variable of this type. 49 * _copy: A procedure pointer to a copying procedure. 50 * _final: A procedure pointer to a wrapper function, which frees 51 allocatable components and calls FINAL subroutines. 52 53 After these follow procedure pointer components for the specific 54 type-bound procedures. */ 55 56 57 #include "config.h" 58 #include "system.h" 59 #include "coretypes.h" 60 #include "gfortran.h" 61 #include "constructor.h" 62 #include "target-memory.h" 63 64 /* Inserts a derived type component reference in a data reference chain. 65 TS: base type of the ref chain so far, in which we will pick the component 66 REF: the address of the GFC_REF pointer to update 67 NAME: name of the component to insert 68 Note that component insertion makes sense only if we are at the end of 69 the chain (*REF == NULL) or if we are adding a missing "_data" component 70 to access the actual contents of a class object. */ 71 72 static void 73 insert_component_ref (gfc_typespec *ts, gfc_ref **ref, const char * const name) 74 { 75 gfc_ref *new_ref; 76 int wcnt, ecnt; 77 78 gcc_assert (ts->type == BT_DERIVED || ts->type == BT_CLASS); 79 80 gfc_find_component (ts->u.derived, name, true, true, &new_ref); 81 82 gfc_get_errors (&wcnt, &ecnt); 83 if (ecnt > 0 && !new_ref) 84 return; 85 gcc_assert (new_ref->u.c.component); 86 87 while (new_ref->next) 88 new_ref = new_ref->next; 89 new_ref->next = *ref; 90 91 if (new_ref->next) 92 { 93 gfc_ref *next = NULL; 94 95 /* We need to update the base type in the trailing reference chain to 96 that of the new component. */ 97 98 gcc_assert (strcmp (name, "_data") == 0); 99 100 if (new_ref->next->type == REF_COMPONENT) 101 next = new_ref->next; 102 else if (new_ref->next->type == REF_ARRAY 103 && new_ref->next->next 104 && new_ref->next->next->type == REF_COMPONENT) 105 next = new_ref->next->next; 106 107 if (next != NULL) 108 { 109 gcc_assert (new_ref->u.c.component->ts.type == BT_CLASS 110 || new_ref->u.c.component->ts.type == BT_DERIVED); 111 next->u.c.sym = new_ref->u.c.component->ts.u.derived; 112 } 113 } 114 115 *ref = new_ref; 116 } 117 118 119 /* Tells whether we need to add a "_data" reference to access REF subobject 120 from an object of type TS. If FIRST_REF_IN_CHAIN is set, then the base 121 object accessed by REF is a variable; in other words it is a full object, 122 not a subobject. */ 123 124 static bool 125 class_data_ref_missing (gfc_typespec *ts, gfc_ref *ref, bool first_ref_in_chain) 126 { 127 /* Only class containers may need the "_data" reference. */ 128 if (ts->type != BT_CLASS) 129 return false; 130 131 /* Accessing a class container with an array reference is certainly wrong. */ 132 if (ref->type != REF_COMPONENT) 133 return true; 134 135 /* Accessing the class container's fields is fine. */ 136 if (ref->u.c.component->name[0] == '_') 137 return false; 138 139 /* At this point we have a class container with a non class container's field 140 component reference. We don't want to add the "_data" component if we are 141 at the first reference and the symbol's type is an extended derived type. 142 In that case, conv_parent_component_references will do the right thing so 143 it is not absolutely necessary. Omitting it prevents a regression (see 144 class_41.f03) in the interface mapping mechanism. When evaluating string 145 lengths depending on dummy arguments, we create a fake symbol with a type 146 equal to that of the dummy type. However, because of type extension, 147 the backend type (corresponding to the actual argument) can have a 148 different (extended) type. Adding the "_data" component explicitly, using 149 the base type, confuses the gfc_conv_component_ref code which deals with 150 the extended type. */ 151 if (first_ref_in_chain && ts->u.derived->attr.extension) 152 return false; 153 154 /* We have a class container with a non class container's field component 155 reference that doesn't fall into the above. */ 156 return true; 157 } 158 159 160 /* Browse through a data reference chain and add the missing "_data" references 161 when a subobject of a class object is accessed without it. 162 Note that it doesn't add the "_data" reference when the class container 163 is the last element in the reference chain. */ 164 165 void 166 gfc_fix_class_refs (gfc_expr *e) 167 { 168 gfc_typespec *ts; 169 gfc_ref **ref; 170 171 if ((e->expr_type != EXPR_VARIABLE 172 && e->expr_type != EXPR_FUNCTION) 173 || (e->expr_type == EXPR_FUNCTION 174 && e->value.function.isym != NULL)) 175 return; 176 177 if (e->expr_type == EXPR_VARIABLE) 178 ts = &e->symtree->n.sym->ts; 179 else 180 { 181 gfc_symbol *func; 182 183 gcc_assert (e->expr_type == EXPR_FUNCTION); 184 if (e->value.function.esym != NULL) 185 func = e->value.function.esym; 186 else 187 func = e->symtree->n.sym; 188 189 if (func->result != NULL) 190 ts = &func->result->ts; 191 else 192 ts = &func->ts; 193 } 194 195 for (ref = &e->ref; *ref != NULL; ref = &(*ref)->next) 196 { 197 if (class_data_ref_missing (ts, *ref, ref == &e->ref)) 198 insert_component_ref (ts, ref, "_data"); 199 200 if ((*ref)->type == REF_COMPONENT) 201 ts = &(*ref)->u.c.component->ts; 202 } 203 } 204 205 206 /* Insert a reference to the component of the given name. 207 Only to be used with CLASS containers and vtables. */ 208 209 void 210 gfc_add_component_ref (gfc_expr *e, const char *name) 211 { 212 gfc_component *c; 213 gfc_ref **tail = &(e->ref); 214 gfc_ref *ref, *next = NULL; 215 gfc_symbol *derived = e->symtree->n.sym->ts.u.derived; 216 while (*tail != NULL) 217 { 218 if ((*tail)->type == REF_COMPONENT) 219 { 220 if (strcmp ((*tail)->u.c.component->name, "_data") == 0 221 && (*tail)->next 222 && (*tail)->next->type == REF_ARRAY 223 && (*tail)->next->next == NULL) 224 return; 225 derived = (*tail)->u.c.component->ts.u.derived; 226 } 227 if ((*tail)->type == REF_ARRAY && (*tail)->next == NULL) 228 break; 229 tail = &((*tail)->next); 230 } 231 if (derived && derived->components && derived->components->next && 232 derived->components->next->ts.type == BT_DERIVED && 233 derived->components->next->ts.u.derived == NULL) 234 { 235 /* Fix up missing vtype. */ 236 gfc_symbol *vtab = gfc_find_derived_vtab (derived->components->ts.u.derived); 237 gcc_assert (vtab); 238 derived->components->next->ts.u.derived = vtab->ts.u.derived; 239 } 240 if (*tail != NULL && strcmp (name, "_data") == 0) 241 next = *tail; 242 else 243 /* Avoid losing memory. */ 244 gfc_free_ref_list (*tail); 245 c = gfc_find_component (derived, name, true, true, tail); 246 247 if (c) { 248 for (ref = *tail; ref->next; ref = ref->next) 249 ; 250 ref->next = next; 251 if (!next) 252 e->ts = c->ts; 253 } 254 } 255 256 257 /* This is used to add both the _data component reference and an array 258 reference to class expressions. Used in translation of intrinsic 259 array inquiry functions. */ 260 261 void 262 gfc_add_class_array_ref (gfc_expr *e) 263 { 264 int rank = CLASS_DATA (e)->as->rank; 265 gfc_array_spec *as = CLASS_DATA (e)->as; 266 gfc_ref *ref = NULL; 267 gfc_add_data_component (e); 268 e->rank = rank; 269 for (ref = e->ref; ref; ref = ref->next) 270 if (!ref->next) 271 break; 272 if (ref->type != REF_ARRAY) 273 { 274 ref->next = gfc_get_ref (); 275 ref = ref->next; 276 ref->type = REF_ARRAY; 277 ref->u.ar.type = AR_FULL; 278 ref->u.ar.as = as; 279 } 280 } 281 282 283 /* Unfortunately, class array expressions can appear in various conditions; 284 with and without both _data component and an arrayspec. This function 285 deals with that variability. The previous reference to 'ref' is to a 286 class array. */ 287 288 static bool 289 class_array_ref_detected (gfc_ref *ref, bool *full_array) 290 { 291 bool no_data = false; 292 bool with_data = false; 293 294 /* An array reference with no _data component. */ 295 if (ref && ref->type == REF_ARRAY 296 && !ref->next 297 && ref->u.ar.type != AR_ELEMENT) 298 { 299 if (full_array) 300 *full_array = ref->u.ar.type == AR_FULL; 301 no_data = true; 302 } 303 304 /* Cover cases where _data appears, with or without an array ref. */ 305 if (ref && ref->type == REF_COMPONENT 306 && strcmp (ref->u.c.component->name, "_data") == 0) 307 { 308 if (!ref->next) 309 { 310 with_data = true; 311 if (full_array) 312 *full_array = true; 313 } 314 else if (ref->next && ref->next->type == REF_ARRAY 315 && ref->type == REF_COMPONENT 316 && ref->next->u.ar.type != AR_ELEMENT) 317 { 318 with_data = true; 319 if (full_array) 320 *full_array = ref->next->u.ar.type == AR_FULL; 321 } 322 } 323 324 return no_data || with_data; 325 } 326 327 328 /* Returns true if the expression contains a reference to a class 329 array. Notice that class array elements return false. */ 330 331 bool 332 gfc_is_class_array_ref (gfc_expr *e, bool *full_array) 333 { 334 gfc_ref *ref; 335 336 if (!e->rank) 337 return false; 338 339 if (full_array) 340 *full_array= false; 341 342 /* Is this a class array object? ie. Is the symbol of type class? */ 343 if (e->symtree 344 && e->symtree->n.sym->ts.type == BT_CLASS 345 && CLASS_DATA (e->symtree->n.sym) 346 && CLASS_DATA (e->symtree->n.sym)->attr.dimension 347 && class_array_ref_detected (e->ref, full_array)) 348 return true; 349 350 /* Or is this a class array component reference? */ 351 for (ref = e->ref; ref; ref = ref->next) 352 { 353 if (ref->type == REF_COMPONENT 354 && ref->u.c.component->ts.type == BT_CLASS 355 && CLASS_DATA (ref->u.c.component)->attr.dimension 356 && class_array_ref_detected (ref->next, full_array)) 357 return true; 358 } 359 360 return false; 361 } 362 363 364 /* Returns true if the expression is a reference to a class 365 scalar. This function is necessary because such expressions 366 can be dressed with a reference to the _data component and so 367 have a type other than BT_CLASS. */ 368 369 bool 370 gfc_is_class_scalar_expr (gfc_expr *e) 371 { 372 gfc_ref *ref; 373 374 if (e->rank) 375 return false; 376 377 /* Is this a class object? */ 378 if (e->symtree 379 && e->symtree->n.sym->ts.type == BT_CLASS 380 && CLASS_DATA (e->symtree->n.sym) 381 && !CLASS_DATA (e->symtree->n.sym)->attr.dimension 382 && (e->ref == NULL 383 || (e->ref->type == REF_COMPONENT 384 && strcmp (e->ref->u.c.component->name, "_data") == 0 385 && e->ref->next == NULL))) 386 return true; 387 388 /* Or is the final reference BT_CLASS or _data? */ 389 for (ref = e->ref; ref; ref = ref->next) 390 { 391 if (ref->type == REF_COMPONENT 392 && ref->u.c.component->ts.type == BT_CLASS 393 && CLASS_DATA (ref->u.c.component) 394 && !CLASS_DATA (ref->u.c.component)->attr.dimension 395 && (ref->next == NULL 396 || (ref->next->type == REF_COMPONENT 397 && strcmp (ref->next->u.c.component->name, "_data") == 0 398 && ref->next->next == NULL))) 399 return true; 400 } 401 402 return false; 403 } 404 405 406 /* Tells whether the expression E is a reference to a (scalar) class container. 407 Scalar because array class containers usually have an array reference after 408 them, and gfc_fix_class_refs will add the missing "_data" component reference 409 in that case. */ 410 411 bool 412 gfc_is_class_container_ref (gfc_expr *e) 413 { 414 gfc_ref *ref; 415 bool result; 416 417 if (e->expr_type != EXPR_VARIABLE) 418 return e->ts.type == BT_CLASS; 419 420 if (e->symtree->n.sym->ts.type == BT_CLASS) 421 result = true; 422 else 423 result = false; 424 425 for (ref = e->ref; ref; ref = ref->next) 426 { 427 if (ref->type != REF_COMPONENT) 428 result = false; 429 else if (ref->u.c.component->ts.type == BT_CLASS) 430 result = true; 431 else 432 result = false; 433 } 434 435 return result; 436 } 437 438 439 /* Build an initializer for CLASS pointers, 440 initializing the _data component to the init_expr (or NULL) and the _vptr 441 component to the corresponding type (or the declared type, given by ts). */ 442 443 gfc_expr * 444 gfc_class_initializer (gfc_typespec *ts, gfc_expr *init_expr) 445 { 446 gfc_expr *init; 447 gfc_component *comp; 448 gfc_symbol *vtab = NULL; 449 450 if (init_expr && init_expr->expr_type != EXPR_NULL) 451 vtab = gfc_find_vtab (&init_expr->ts); 452 else 453 vtab = gfc_find_vtab (ts); 454 455 init = gfc_get_structure_constructor_expr (ts->type, ts->kind, 456 &ts->u.derived->declared_at); 457 init->ts = *ts; 458 459 for (comp = ts->u.derived->components; comp; comp = comp->next) 460 { 461 gfc_constructor *ctor = gfc_constructor_get(); 462 if (strcmp (comp->name, "_vptr") == 0 && vtab) 463 ctor->expr = gfc_lval_expr_from_sym (vtab); 464 else if (init_expr && init_expr->expr_type != EXPR_NULL) 465 ctor->expr = gfc_copy_expr (init_expr); 466 else 467 ctor->expr = gfc_get_null_expr (NULL); 468 gfc_constructor_append (&init->value.constructor, ctor); 469 } 470 471 return init; 472 } 473 474 475 /* Create a unique string identifier for a derived type, composed of its name 476 and module name. This is used to construct unique names for the class 477 containers and vtab symbols. */ 478 479 static char * 480 get_unique_type_string (gfc_symbol *derived) 481 { 482 const char *dt_name; 483 char *string; 484 size_t len; 485 if (derived->attr.unlimited_polymorphic) 486 dt_name = "STAR"; 487 else 488 dt_name = gfc_dt_upper_string (derived->name); 489 len = strlen (dt_name) + 2; 490 if (derived->attr.unlimited_polymorphic) 491 { 492 string = XNEWVEC (char, len); 493 sprintf (string, "_%s", dt_name); 494 } 495 else if (derived->module) 496 { 497 string = XNEWVEC (char, strlen (derived->module) + len); 498 sprintf (string, "%s_%s", derived->module, dt_name); 499 } 500 else if (derived->ns->proc_name) 501 { 502 string = XNEWVEC (char, strlen (derived->ns->proc_name->name) + len); 503 sprintf (string, "%s_%s", derived->ns->proc_name->name, dt_name); 504 } 505 else 506 { 507 string = XNEWVEC (char, len); 508 sprintf (string, "_%s", dt_name); 509 } 510 return string; 511 } 512 513 514 /* A relative of 'get_unique_type_string' which makes sure the generated 515 string will not be too long (replacing it by a hash string if needed). */ 516 517 static void 518 get_unique_hashed_string (char *string, gfc_symbol *derived) 519 { 520 /* Provide sufficient space to hold "symbol.symbol_symbol". */ 521 char *tmp; 522 tmp = get_unique_type_string (derived); 523 /* If string is too long, use hash value in hex representation (allow for 524 extra decoration, cf. gfc_build_class_symbol & gfc_find_derived_vtab). 525 We need space to for 15 characters "__class_" + symbol name + "_%d_%da", 526 where %d is the (co)rank which can be up to n = 15. */ 527 if (strlen (tmp) > GFC_MAX_SYMBOL_LEN - 15) 528 { 529 int h = gfc_hash_value (derived); 530 sprintf (string, "%X", h); 531 } 532 else 533 strcpy (string, tmp); 534 free (tmp); 535 } 536 537 538 /* Assign a hash value for a derived type. The algorithm is that of SDBM. */ 539 540 unsigned int 541 gfc_hash_value (gfc_symbol *sym) 542 { 543 unsigned int hash = 0; 544 /* Provide sufficient space to hold "symbol.symbol_symbol". */ 545 char *c; 546 int i, len; 547 548 c = get_unique_type_string (sym); 549 len = strlen (c); 550 551 for (i = 0; i < len; i++) 552 hash = (hash << 6) + (hash << 16) - hash + c[i]; 553 554 free (c); 555 /* Return the hash but take the modulus for the sake of module read, 556 even though this slightly increases the chance of collision. */ 557 return (hash % 100000000); 558 } 559 560 561 /* Assign a hash value for an intrinsic type. The algorithm is that of SDBM. */ 562 563 unsigned int 564 gfc_intrinsic_hash_value (gfc_typespec *ts) 565 { 566 unsigned int hash = 0; 567 const char *c = gfc_typename (ts, true); 568 int i, len; 569 570 len = strlen (c); 571 572 for (i = 0; i < len; i++) 573 hash = (hash << 6) + (hash << 16) - hash + c[i]; 574 575 /* Return the hash but take the modulus for the sake of module read, 576 even though this slightly increases the chance of collision. */ 577 return (hash % 100000000); 578 } 579 580 581 /* Get the _len component from a class/derived object storing a string. 582 For unlimited polymorphic entities a ref to the _data component is available 583 while a ref to the _len component is needed. This routine traverese the 584 ref-chain and strips the last ref to a _data from it replacing it with a 585 ref to the _len component. */ 586 587 gfc_expr * 588 gfc_get_len_component (gfc_expr *e, int k) 589 { 590 gfc_expr *ptr; 591 gfc_ref *ref, **last; 592 593 ptr = gfc_copy_expr (e); 594 595 /* We need to remove the last _data component ref from ptr. */ 596 last = &(ptr->ref); 597 ref = ptr->ref; 598 while (ref) 599 { 600 if (!ref->next 601 && ref->type == REF_COMPONENT 602 && strcmp ("_data", ref->u.c.component->name)== 0) 603 { 604 gfc_free_ref_list (ref); 605 *last = NULL; 606 break; 607 } 608 last = &(ref->next); 609 ref = ref->next; 610 } 611 /* And replace if with a ref to the _len component. */ 612 gfc_add_len_component (ptr); 613 if (k != ptr->ts.kind) 614 { 615 gfc_typespec ts; 616 gfc_clear_ts (&ts); 617 ts.type = BT_INTEGER; 618 ts.kind = k; 619 gfc_convert_type_warn (ptr, &ts, 2, 0); 620 } 621 return ptr; 622 } 623 624 625 /* Build a polymorphic CLASS entity, using the symbol that comes from 626 build_sym. A CLASS entity is represented by an encapsulating type, 627 which contains the declared type as '_data' component, plus a pointer 628 component '_vptr' which determines the dynamic type. When this CLASS 629 entity is unlimited polymorphic, then also add a component '_len' to 630 store the length of string when that is stored in it. */ 631 static int ctr = 0; 632 633 bool 634 gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr, 635 gfc_array_spec **as) 636 { 637 char tname[GFC_MAX_SYMBOL_LEN+1]; 638 char *name; 639 gfc_symbol *fclass; 640 gfc_symbol *vtab; 641 gfc_component *c; 642 gfc_namespace *ns; 643 int rank; 644 645 gcc_assert (as); 646 647 if (attr->class_ok) 648 /* Class container has already been built. */ 649 return true; 650 651 attr->class_ok = attr->dummy || attr->pointer || attr->allocatable 652 || attr->select_type_temporary || attr->associate_var; 653 654 if (!attr->class_ok) 655 /* We cannot build the class container yet. */ 656 return true; 657 658 /* Determine the name of the encapsulating type. */ 659 rank = !(*as) || (*as)->rank == -1 ? GFC_MAX_DIMENSIONS : (*as)->rank; 660 661 if (!ts->u.derived) 662 return false; 663 664 get_unique_hashed_string (tname, ts->u.derived); 665 if ((*as) && attr->allocatable) 666 name = xasprintf ("__class_%s_%d_%da", tname, rank, (*as)->corank); 667 else if ((*as) && attr->pointer) 668 name = xasprintf ("__class_%s_%d_%dp", tname, rank, (*as)->corank); 669 else if ((*as)) 670 name = xasprintf ("__class_%s_%d_%dt", tname, rank, (*as)->corank); 671 else if (attr->pointer) 672 name = xasprintf ("__class_%s_p", tname); 673 else if (attr->allocatable) 674 name = xasprintf ("__class_%s_a", tname); 675 else 676 name = xasprintf ("__class_%s_t", tname); 677 678 if (ts->u.derived->attr.unlimited_polymorphic) 679 { 680 /* Find the top-level namespace. */ 681 for (ns = gfc_current_ns; ns; ns = ns->parent) 682 if (!ns->parent) 683 break; 684 } 685 else 686 ns = ts->u.derived->ns; 687 688 /* Although this might seem to be counterintuitive, we can build separate 689 class types with different array specs because the TKR interface checks 690 work on the declared type. All array type other than deferred shape or 691 assumed rank are added to the function namespace to ensure that they 692 are properly distinguished. */ 693 if (attr->dummy && !attr->codimension && (*as) 694 && !((*as)->type == AS_DEFERRED || (*as)->type == AS_ASSUMED_RANK)) 695 { 696 char *sname; 697 ns = gfc_current_ns; 698 gfc_find_symbol (name, ns, 0, &fclass); 699 /* If a local class type with this name already exists, update the 700 name with an index. */ 701 if (fclass) 702 { 703 fclass = NULL; 704 sname = xasprintf ("%s_%d", name, ++ctr); 705 free (name); 706 name = sname; 707 } 708 } 709 else 710 gfc_find_symbol (name, ns, 0, &fclass); 711 712 if (fclass == NULL) 713 { 714 gfc_symtree *st; 715 /* If not there, create a new symbol. */ 716 fclass = gfc_new_symbol (name, ns); 717 st = gfc_new_symtree (&ns->sym_root, name); 718 st->n.sym = fclass; 719 gfc_set_sym_referenced (fclass); 720 fclass->refs++; 721 fclass->ts.type = BT_UNKNOWN; 722 if (!ts->u.derived->attr.unlimited_polymorphic) 723 fclass->attr.abstract = ts->u.derived->attr.abstract; 724 fclass->f2k_derived = gfc_get_namespace (NULL, 0); 725 if (!gfc_add_flavor (&fclass->attr, FL_DERIVED, NULL, 726 &gfc_current_locus)) 727 return false; 728 729 /* Add component '_data'. */ 730 if (!gfc_add_component (fclass, "_data", &c)) 731 return false; 732 c->ts = *ts; 733 c->ts.type = BT_DERIVED; 734 c->attr.access = ACCESS_PRIVATE; 735 c->ts.u.derived = ts->u.derived; 736 c->attr.class_pointer = attr->pointer; 737 c->attr.pointer = attr->pointer || (attr->dummy && !attr->allocatable) 738 || attr->select_type_temporary; 739 c->attr.allocatable = attr->allocatable; 740 c->attr.dimension = attr->dimension; 741 c->attr.codimension = attr->codimension; 742 c->attr.abstract = fclass->attr.abstract; 743 c->as = (*as); 744 c->initializer = NULL; 745 746 /* Add component '_vptr'. */ 747 if (!gfc_add_component (fclass, "_vptr", &c)) 748 return false; 749 c->ts.type = BT_DERIVED; 750 c->attr.access = ACCESS_PRIVATE; 751 c->attr.pointer = 1; 752 753 if (ts->u.derived->attr.unlimited_polymorphic) 754 { 755 vtab = gfc_find_derived_vtab (ts->u.derived); 756 gcc_assert (vtab); 757 c->ts.u.derived = vtab->ts.u.derived; 758 759 /* Add component '_len'. Only unlimited polymorphic pointers may 760 have a string assigned to them, i.e., only those need the _len 761 component. */ 762 if (!gfc_add_component (fclass, "_len", &c)) 763 return false; 764 c->ts.type = BT_INTEGER; 765 c->ts.kind = gfc_charlen_int_kind; 766 c->attr.access = ACCESS_PRIVATE; 767 c->attr.artificial = 1; 768 } 769 else 770 /* Build vtab later. */ 771 c->ts.u.derived = NULL; 772 } 773 774 if (!ts->u.derived->attr.unlimited_polymorphic) 775 { 776 /* Since the extension field is 8 bit wide, we can only have 777 up to 255 extension levels. */ 778 if (ts->u.derived->attr.extension == 255) 779 { 780 gfc_error ("Maximum extension level reached with type %qs at %L", 781 ts->u.derived->name, &ts->u.derived->declared_at); 782 return false; 783 } 784 785 fclass->attr.extension = ts->u.derived->attr.extension + 1; 786 fclass->attr.alloc_comp = ts->u.derived->attr.alloc_comp; 787 fclass->attr.coarray_comp = ts->u.derived->attr.coarray_comp; 788 } 789 790 fclass->attr.is_class = 1; 791 ts->u.derived = fclass; 792 attr->allocatable = attr->pointer = attr->dimension = attr->codimension = 0; 793 (*as) = NULL; 794 free (name); 795 return true; 796 } 797 798 799 /* Add a procedure pointer component to the vtype 800 to represent a specific type-bound procedure. */ 801 802 static void 803 add_proc_comp (gfc_symbol *vtype, const char *name, gfc_typebound_proc *tb) 804 { 805 gfc_component *c; 806 807 if (tb->non_overridable && !tb->overridden) 808 return; 809 810 c = gfc_find_component (vtype, name, true, true, NULL); 811 812 if (c == NULL) 813 { 814 /* Add procedure component. */ 815 if (!gfc_add_component (vtype, name, &c)) 816 return; 817 818 if (!c->tb) 819 c->tb = XCNEW (gfc_typebound_proc); 820 *c->tb = *tb; 821 c->tb->ppc = 1; 822 c->attr.procedure = 1; 823 c->attr.proc_pointer = 1; 824 c->attr.flavor = FL_PROCEDURE; 825 c->attr.access = ACCESS_PRIVATE; 826 c->attr.external = 1; 827 c->attr.untyped = 1; 828 c->attr.if_source = IFSRC_IFBODY; 829 } 830 else if (c->attr.proc_pointer && c->tb) 831 { 832 *c->tb = *tb; 833 c->tb->ppc = 1; 834 } 835 836 if (tb->u.specific) 837 { 838 gfc_symbol *ifc = tb->u.specific->n.sym; 839 c->ts.interface = ifc; 840 if (!tb->deferred) 841 c->initializer = gfc_get_variable_expr (tb->u.specific); 842 c->attr.pure = ifc->attr.pure; 843 } 844 } 845 846 847 /* Add all specific type-bound procedures in the symtree 'st' to a vtype. */ 848 849 static void 850 add_procs_to_declared_vtab1 (gfc_symtree *st, gfc_symbol *vtype) 851 { 852 if (!st) 853 return; 854 855 if (st->left) 856 add_procs_to_declared_vtab1 (st->left, vtype); 857 858 if (st->right) 859 add_procs_to_declared_vtab1 (st->right, vtype); 860 861 if (st->n.tb && !st->n.tb->error 862 && !st->n.tb->is_generic && st->n.tb->u.specific) 863 add_proc_comp (vtype, st->name, st->n.tb); 864 } 865 866 867 /* Copy procedure pointers components from the parent type. */ 868 869 static void 870 copy_vtab_proc_comps (gfc_symbol *declared, gfc_symbol *vtype) 871 { 872 gfc_component *cmp; 873 gfc_symbol *vtab; 874 875 vtab = gfc_find_derived_vtab (declared); 876 877 for (cmp = vtab->ts.u.derived->components; cmp; cmp = cmp->next) 878 { 879 if (gfc_find_component (vtype, cmp->name, true, true, NULL)) 880 continue; 881 882 add_proc_comp (vtype, cmp->name, cmp->tb); 883 } 884 } 885 886 887 /* Returns true if any of its nonpointer nonallocatable components or 888 their nonpointer nonallocatable subcomponents has a finalization 889 subroutine. */ 890 891 static bool 892 has_finalizer_component (gfc_symbol *derived) 893 { 894 gfc_component *c; 895 896 for (c = derived->components; c; c = c->next) 897 if (c->ts.type == BT_DERIVED && !c->attr.pointer && !c->attr.allocatable) 898 { 899 if (c->ts.u.derived->f2k_derived 900 && c->ts.u.derived->f2k_derived->finalizers) 901 return true; 902 903 /* Stop infinite recursion through this function by inhibiting 904 calls when the derived type and that of the component are 905 the same. */ 906 if (!gfc_compare_derived_types (derived, c->ts.u.derived) 907 && has_finalizer_component (c->ts.u.derived)) 908 return true; 909 } 910 return false; 911 } 912 913 914 static bool 915 comp_is_finalizable (gfc_component *comp) 916 { 917 if (comp->attr.proc_pointer) 918 return false; 919 else if (comp->attr.allocatable && comp->ts.type != BT_CLASS) 920 return true; 921 else if (comp->ts.type == BT_DERIVED && !comp->attr.pointer 922 && (comp->ts.u.derived->attr.alloc_comp 923 || has_finalizer_component (comp->ts.u.derived) 924 || (comp->ts.u.derived->f2k_derived 925 && comp->ts.u.derived->f2k_derived->finalizers))) 926 return true; 927 else if (comp->ts.type == BT_CLASS && CLASS_DATA (comp) 928 && CLASS_DATA (comp)->attr.allocatable) 929 return true; 930 else 931 return false; 932 } 933 934 935 /* Call DEALLOCATE for the passed component if it is allocatable, if it is 936 neither allocatable nor a pointer but has a finalizer, call it. If it 937 is a nonpointer component with allocatable components or has finalizers, walk 938 them. Either of them is required; other nonallocatables and pointers aren't 939 handled gracefully. 940 Note: If the component is allocatable, the DEALLOCATE handling takes care 941 of calling the appropriate finalizers, coarray deregistering, and 942 deallocation of allocatable subcomponents. */ 943 944 static void 945 finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp, 946 gfc_symbol *stat, gfc_symbol *fini_coarray, gfc_code **code, 947 gfc_namespace *sub_ns) 948 { 949 gfc_expr *e; 950 gfc_ref *ref; 951 gfc_was_finalized *f; 952 953 if (!comp_is_finalizable (comp)) 954 return; 955 956 /* If this expression with this component has been finalized 957 already in this namespace, there is nothing to do. */ 958 for (f = sub_ns->was_finalized; f; f = f->next) 959 { 960 if (f->e == expr && f->c == comp) 961 return; 962 } 963 964 e = gfc_copy_expr (expr); 965 if (!e->ref) 966 e->ref = ref = gfc_get_ref (); 967 else 968 { 969 for (ref = e->ref; ref->next; ref = ref->next) 970 ; 971 ref->next = gfc_get_ref (); 972 ref = ref->next; 973 } 974 ref->type = REF_COMPONENT; 975 ref->u.c.sym = derived; 976 ref->u.c.component = comp; 977 e->ts = comp->ts; 978 979 if (comp->attr.dimension || comp->attr.codimension 980 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp) 981 && (CLASS_DATA (comp)->attr.dimension 982 || CLASS_DATA (comp)->attr.codimension))) 983 { 984 ref->next = gfc_get_ref (); 985 ref->next->type = REF_ARRAY; 986 ref->next->u.ar.dimen = 0; 987 ref->next->u.ar.as = comp->ts.type == BT_CLASS ? CLASS_DATA (comp)->as 988 : comp->as; 989 e->rank = ref->next->u.ar.as->rank; 990 ref->next->u.ar.type = e->rank ? AR_FULL : AR_ELEMENT; 991 } 992 993 /* Call DEALLOCATE (comp, stat=ignore). */ 994 if (comp->attr.allocatable 995 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp) 996 && CLASS_DATA (comp)->attr.allocatable)) 997 { 998 gfc_code *dealloc, *block = NULL; 999 1000 /* Add IF (fini_coarray). */ 1001 if (comp->attr.codimension 1002 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp) 1003 && CLASS_DATA (comp)->attr.codimension)) 1004 { 1005 block = gfc_get_code (EXEC_IF); 1006 if (*code) 1007 { 1008 (*code)->next = block; 1009 (*code) = (*code)->next; 1010 } 1011 else 1012 (*code) = block; 1013 1014 block->block = gfc_get_code (EXEC_IF); 1015 block = block->block; 1016 block->expr1 = gfc_lval_expr_from_sym (fini_coarray); 1017 } 1018 1019 dealloc = gfc_get_code (EXEC_DEALLOCATE); 1020 1021 dealloc->ext.alloc.list = gfc_get_alloc (); 1022 dealloc->ext.alloc.list->expr = e; 1023 dealloc->expr1 = gfc_lval_expr_from_sym (stat); 1024 1025 gfc_code *cond = gfc_get_code (EXEC_IF); 1026 cond->block = gfc_get_code (EXEC_IF); 1027 cond->block->expr1 = gfc_get_expr (); 1028 cond->block->expr1->expr_type = EXPR_FUNCTION; 1029 cond->block->expr1->where = gfc_current_locus; 1030 gfc_get_sym_tree ("associated", sub_ns, &cond->block->expr1->symtree, false); 1031 cond->block->expr1->symtree->n.sym->attr.flavor = FL_PROCEDURE; 1032 cond->block->expr1->symtree->n.sym->attr.intrinsic = 1; 1033 cond->block->expr1->symtree->n.sym->result = cond->block->expr1->symtree->n.sym; 1034 gfc_commit_symbol (cond->block->expr1->symtree->n.sym); 1035 cond->block->expr1->ts.type = BT_LOGICAL; 1036 cond->block->expr1->ts.kind = gfc_default_logical_kind; 1037 cond->block->expr1->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_ASSOCIATED); 1038 cond->block->expr1->value.function.actual = gfc_get_actual_arglist (); 1039 cond->block->expr1->value.function.actual->expr = gfc_copy_expr (expr); 1040 cond->block->expr1->value.function.actual->next = gfc_get_actual_arglist (); 1041 cond->block->next = dealloc; 1042 1043 if (block) 1044 block->next = cond; 1045 else if (*code) 1046 { 1047 (*code)->next = cond; 1048 (*code) = (*code)->next; 1049 } 1050 else 1051 (*code) = cond; 1052 1053 } 1054 else if (comp->ts.type == BT_DERIVED 1055 && comp->ts.u.derived->f2k_derived 1056 && comp->ts.u.derived->f2k_derived->finalizers) 1057 { 1058 /* Call FINAL_WRAPPER (comp); */ 1059 gfc_code *final_wrap; 1060 gfc_symbol *vtab; 1061 gfc_component *c; 1062 1063 vtab = gfc_find_derived_vtab (comp->ts.u.derived); 1064 for (c = vtab->ts.u.derived->components; c; c = c->next) 1065 if (strcmp (c->name, "_final") == 0) 1066 break; 1067 1068 gcc_assert (c); 1069 final_wrap = gfc_get_code (EXEC_CALL); 1070 final_wrap->symtree = c->initializer->symtree; 1071 final_wrap->resolved_sym = c->initializer->symtree->n.sym; 1072 final_wrap->ext.actual = gfc_get_actual_arglist (); 1073 final_wrap->ext.actual->expr = e; 1074 1075 if (*code) 1076 { 1077 (*code)->next = final_wrap; 1078 (*code) = (*code)->next; 1079 } 1080 else 1081 (*code) = final_wrap; 1082 } 1083 else 1084 { 1085 gfc_component *c; 1086 1087 for (c = comp->ts.u.derived->components; c; c = c->next) 1088 finalize_component (e, comp->ts.u.derived, c, stat, fini_coarray, code, 1089 sub_ns); 1090 gfc_free_expr (e); 1091 } 1092 1093 /* Record that this was finalized already in this namespace. */ 1094 f = sub_ns->was_finalized; 1095 sub_ns->was_finalized = XCNEW (gfc_was_finalized); 1096 sub_ns->was_finalized->e = expr; 1097 sub_ns->was_finalized->c = comp; 1098 sub_ns->was_finalized->next = f; 1099 } 1100 1101 1102 /* Generate code equivalent to 1103 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr) 1104 + offset, c_ptr), ptr). */ 1105 1106 static gfc_code * 1107 finalization_scalarizer (gfc_symbol *array, gfc_symbol *ptr, 1108 gfc_expr *offset, gfc_namespace *sub_ns) 1109 { 1110 gfc_code *block; 1111 gfc_expr *expr, *expr2; 1112 1113 /* C_F_POINTER(). */ 1114 block = gfc_get_code (EXEC_CALL); 1115 gfc_get_sym_tree ("c_f_pointer", sub_ns, &block->symtree, true); 1116 block->resolved_sym = block->symtree->n.sym; 1117 block->resolved_sym->attr.flavor = FL_PROCEDURE; 1118 block->resolved_sym->attr.intrinsic = 1; 1119 block->resolved_sym->attr.subroutine = 1; 1120 block->resolved_sym->from_intmod = INTMOD_ISO_C_BINDING; 1121 block->resolved_sym->intmod_sym_id = ISOCBINDING_F_POINTER; 1122 block->resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_C_F_POINTER); 1123 gfc_commit_symbol (block->resolved_sym); 1124 1125 /* C_F_POINTER's first argument: TRANSFER ( <addr>, c_intptr_t). */ 1126 block->ext.actual = gfc_get_actual_arglist (); 1127 block->ext.actual->next = gfc_get_actual_arglist (); 1128 block->ext.actual->next->expr = gfc_get_int_expr (gfc_index_integer_kind, 1129 NULL, 0); 1130 block->ext.actual->next->next = gfc_get_actual_arglist (); /* SIZE. */ 1131 1132 /* The <addr> part: TRANSFER (C_LOC (array), c_intptr_t). */ 1133 1134 /* TRANSFER's first argument: C_LOC (array). */ 1135 expr = gfc_get_expr (); 1136 expr->expr_type = EXPR_FUNCTION; 1137 gfc_get_sym_tree ("c_loc", sub_ns, &expr->symtree, false); 1138 expr->symtree->n.sym->attr.flavor = FL_PROCEDURE; 1139 expr->symtree->n.sym->intmod_sym_id = ISOCBINDING_LOC; 1140 expr->symtree->n.sym->attr.intrinsic = 1; 1141 expr->symtree->n.sym->from_intmod = INTMOD_ISO_C_BINDING; 1142 expr->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_C_LOC); 1143 expr->value.function.actual = gfc_get_actual_arglist (); 1144 expr->value.function.actual->expr 1145 = gfc_lval_expr_from_sym (array); 1146 expr->symtree->n.sym->result = expr->symtree->n.sym; 1147 gfc_commit_symbol (expr->symtree->n.sym); 1148 expr->ts.type = BT_INTEGER; 1149 expr->ts.kind = gfc_index_integer_kind; 1150 expr->where = gfc_current_locus; 1151 1152 /* TRANSFER. */ 1153 expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_TRANSFER, "transfer", 1154 gfc_current_locus, 3, expr, 1155 gfc_get_int_expr (gfc_index_integer_kind, 1156 NULL, 0), NULL); 1157 expr2->ts.type = BT_INTEGER; 1158 expr2->ts.kind = gfc_index_integer_kind; 1159 1160 /* <array addr> + <offset>. */ 1161 block->ext.actual->expr = gfc_get_expr (); 1162 block->ext.actual->expr->expr_type = EXPR_OP; 1163 block->ext.actual->expr->value.op.op = INTRINSIC_PLUS; 1164 block->ext.actual->expr->value.op.op1 = expr2; 1165 block->ext.actual->expr->value.op.op2 = offset; 1166 block->ext.actual->expr->ts = expr->ts; 1167 block->ext.actual->expr->where = gfc_current_locus; 1168 1169 /* C_F_POINTER's 2nd arg: ptr -- and its absent shape=. */ 1170 block->ext.actual->next = gfc_get_actual_arglist (); 1171 block->ext.actual->next->expr = gfc_lval_expr_from_sym (ptr); 1172 block->ext.actual->next->next = gfc_get_actual_arglist (); 1173 1174 return block; 1175 } 1176 1177 1178 /* Calculates the offset to the (idx+1)th element of an array, taking the 1179 stride into account. It generates the code: 1180 offset = 0 1181 do idx2 = 1, rank 1182 offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1) * strides(idx2) 1183 end do 1184 offset = offset * byte_stride. */ 1185 1186 static gfc_code* 1187 finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset, 1188 gfc_symbol *strides, gfc_symbol *sizes, 1189 gfc_symbol *byte_stride, gfc_expr *rank, 1190 gfc_code *block, gfc_namespace *sub_ns) 1191 { 1192 gfc_iterator *iter; 1193 gfc_expr *expr, *expr2; 1194 1195 /* offset = 0. */ 1196 block->next = gfc_get_code (EXEC_ASSIGN); 1197 block = block->next; 1198 block->expr1 = gfc_lval_expr_from_sym (offset); 1199 block->expr2 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0); 1200 1201 /* Create loop. */ 1202 iter = gfc_get_iterator (); 1203 iter->var = gfc_lval_expr_from_sym (idx2); 1204 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1); 1205 iter->end = gfc_copy_expr (rank); 1206 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1); 1207 block->next = gfc_get_code (EXEC_DO); 1208 block = block->next; 1209 block->ext.iterator = iter; 1210 block->block = gfc_get_code (EXEC_DO); 1211 1212 /* Loop body: offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1) 1213 * strides(idx2). */ 1214 1215 /* mod (idx, sizes(idx2)). */ 1216 expr = gfc_lval_expr_from_sym (sizes); 1217 expr->ref = gfc_get_ref (); 1218 expr->ref->type = REF_ARRAY; 1219 expr->ref->u.ar.as = sizes->as; 1220 expr->ref->u.ar.type = AR_ELEMENT; 1221 expr->ref->u.ar.dimen = 1; 1222 expr->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT; 1223 expr->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2); 1224 expr->where = sizes->declared_at; 1225 1226 expr = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_MOD, "mod", 1227 gfc_current_locus, 2, 1228 gfc_lval_expr_from_sym (idx), expr); 1229 expr->ts = idx->ts; 1230 1231 /* (...) / sizes(idx2-1). */ 1232 expr2 = gfc_get_expr (); 1233 expr2->expr_type = EXPR_OP; 1234 expr2->value.op.op = INTRINSIC_DIVIDE; 1235 expr2->value.op.op1 = expr; 1236 expr2->value.op.op2 = gfc_lval_expr_from_sym (sizes); 1237 expr2->value.op.op2->ref = gfc_get_ref (); 1238 expr2->value.op.op2->ref->type = REF_ARRAY; 1239 expr2->value.op.op2->ref->u.ar.as = sizes->as; 1240 expr2->value.op.op2->ref->u.ar.type = AR_ELEMENT; 1241 expr2->value.op.op2->ref->u.ar.dimen = 1; 1242 expr2->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT; 1243 expr2->value.op.op2->ref->u.ar.start[0] = gfc_get_expr (); 1244 expr2->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP; 1245 expr2->value.op.op2->ref->u.ar.start[0]->where = gfc_current_locus; 1246 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS; 1247 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1 1248 = gfc_lval_expr_from_sym (idx2); 1249 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op2 1250 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1); 1251 expr2->value.op.op2->ref->u.ar.start[0]->ts 1252 = expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts; 1253 expr2->ts = idx->ts; 1254 expr2->where = gfc_current_locus; 1255 1256 /* ... * strides(idx2). */ 1257 expr = gfc_get_expr (); 1258 expr->expr_type = EXPR_OP; 1259 expr->value.op.op = INTRINSIC_TIMES; 1260 expr->value.op.op1 = expr2; 1261 expr->value.op.op2 = gfc_lval_expr_from_sym (strides); 1262 expr->value.op.op2->ref = gfc_get_ref (); 1263 expr->value.op.op2->ref->type = REF_ARRAY; 1264 expr->value.op.op2->ref->u.ar.type = AR_ELEMENT; 1265 expr->value.op.op2->ref->u.ar.dimen = 1; 1266 expr->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT; 1267 expr->value.op.op2->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2); 1268 expr->value.op.op2->ref->u.ar.as = strides->as; 1269 expr->ts = idx->ts; 1270 expr->where = gfc_current_locus; 1271 1272 /* offset = offset + ... */ 1273 block->block->next = gfc_get_code (EXEC_ASSIGN); 1274 block->block->next->expr1 = gfc_lval_expr_from_sym (offset); 1275 block->block->next->expr2 = gfc_get_expr (); 1276 block->block->next->expr2->expr_type = EXPR_OP; 1277 block->block->next->expr2->value.op.op = INTRINSIC_PLUS; 1278 block->block->next->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset); 1279 block->block->next->expr2->value.op.op2 = expr; 1280 block->block->next->expr2->ts = idx->ts; 1281 block->block->next->expr2->where = gfc_current_locus; 1282 1283 /* After the loop: offset = offset * byte_stride. */ 1284 block->next = gfc_get_code (EXEC_ASSIGN); 1285 block = block->next; 1286 block->expr1 = gfc_lval_expr_from_sym (offset); 1287 block->expr2 = gfc_get_expr (); 1288 block->expr2->expr_type = EXPR_OP; 1289 block->expr2->value.op.op = INTRINSIC_TIMES; 1290 block->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset); 1291 block->expr2->value.op.op2 = gfc_lval_expr_from_sym (byte_stride); 1292 block->expr2->ts = block->expr2->value.op.op1->ts; 1293 block->expr2->where = gfc_current_locus; 1294 return block; 1295 } 1296 1297 1298 /* Insert code of the following form: 1299 1300 block 1301 integer(c_intptr_t) :: i 1302 1303 if ((byte_stride == STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE 1304 && (is_contiguous || !final_rank3->attr.contiguous 1305 || final_rank3->as->type != AS_ASSUMED_SHAPE)) 1306 || 0 == STORAGE_SIZE (array)) then 1307 call final_rank3 (array) 1308 else 1309 block 1310 integer(c_intptr_t) :: offset, j 1311 type(t) :: tmp(shape (array)) 1312 1313 do i = 0, size (array)-1 1314 offset = obtain_offset(i, strides, sizes, byte_stride) 1315 addr = transfer (c_loc (array), addr) + offset 1316 call c_f_pointer (transfer (addr, cptr), ptr) 1317 1318 addr = transfer (c_loc (tmp), addr) 1319 + i * STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE 1320 call c_f_pointer (transfer (addr, cptr), ptr2) 1321 ptr2 = ptr 1322 end do 1323 call final_rank3 (tmp) 1324 end block 1325 end if 1326 block */ 1327 1328 static void 1329 finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini, 1330 gfc_symbol *array, gfc_symbol *byte_stride, 1331 gfc_symbol *idx, gfc_symbol *ptr, 1332 gfc_symbol *nelem, 1333 gfc_symbol *strides, gfc_symbol *sizes, 1334 gfc_symbol *idx2, gfc_symbol *offset, 1335 gfc_symbol *is_contiguous, gfc_expr *rank, 1336 gfc_namespace *sub_ns) 1337 { 1338 gfc_symbol *tmp_array, *ptr2; 1339 gfc_expr *size_expr, *offset2, *expr; 1340 gfc_namespace *ns; 1341 gfc_iterator *iter; 1342 gfc_code *block2; 1343 int i; 1344 1345 block->next = gfc_get_code (EXEC_IF); 1346 block = block->next; 1347 1348 block->block = gfc_get_code (EXEC_IF); 1349 block = block->block; 1350 1351 /* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE. */ 1352 size_expr = gfc_get_expr (); 1353 size_expr->where = gfc_current_locus; 1354 size_expr->expr_type = EXPR_OP; 1355 size_expr->value.op.op = INTRINSIC_DIVIDE; 1356 1357 /* STORAGE_SIZE (array,kind=c_intptr_t). */ 1358 size_expr->value.op.op1 1359 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STORAGE_SIZE, 1360 "storage_size", gfc_current_locus, 2, 1361 gfc_lval_expr_from_sym (array), 1362 gfc_get_int_expr (gfc_index_integer_kind, 1363 NULL, 0)); 1364 1365 /* NUMERIC_STORAGE_SIZE. */ 1366 size_expr->value.op.op2 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1367 gfc_character_storage_size); 1368 size_expr->value.op.op1->ts = size_expr->value.op.op2->ts; 1369 size_expr->ts = size_expr->value.op.op1->ts; 1370 1371 /* IF condition: (stride == size_expr 1372 && ((fini's as->ASSUMED_SIZE && !fini's attr.contiguous) 1373 || is_contiguous) 1374 || 0 == size_expr. */ 1375 block->expr1 = gfc_get_expr (); 1376 block->expr1->ts.type = BT_LOGICAL; 1377 block->expr1->ts.kind = gfc_default_logical_kind; 1378 block->expr1->expr_type = EXPR_OP; 1379 block->expr1->where = gfc_current_locus; 1380 1381 block->expr1->value.op.op = INTRINSIC_OR; 1382 1383 /* byte_stride == size_expr */ 1384 expr = gfc_get_expr (); 1385 expr->ts.type = BT_LOGICAL; 1386 expr->ts.kind = gfc_default_logical_kind; 1387 expr->expr_type = EXPR_OP; 1388 expr->where = gfc_current_locus; 1389 expr->value.op.op = INTRINSIC_EQ; 1390 expr->value.op.op1 1391 = gfc_lval_expr_from_sym (byte_stride); 1392 expr->value.op.op2 = size_expr; 1393 1394 /* If strides aren't allowed (not assumed shape or CONTIGUOUS), 1395 add is_contiguous check. */ 1396 1397 if (fini->proc_tree->n.sym->formal->sym->as->type != AS_ASSUMED_SHAPE 1398 || fini->proc_tree->n.sym->formal->sym->attr.contiguous) 1399 { 1400 gfc_expr *expr2; 1401 expr2 = gfc_get_expr (); 1402 expr2->ts.type = BT_LOGICAL; 1403 expr2->ts.kind = gfc_default_logical_kind; 1404 expr2->expr_type = EXPR_OP; 1405 expr2->where = gfc_current_locus; 1406 expr2->value.op.op = INTRINSIC_AND; 1407 expr2->value.op.op1 = expr; 1408 expr2->value.op.op2 = gfc_lval_expr_from_sym (is_contiguous); 1409 expr = expr2; 1410 } 1411 1412 block->expr1->value.op.op1 = expr; 1413 1414 /* 0 == size_expr */ 1415 block->expr1->value.op.op2 = gfc_get_expr (); 1416 block->expr1->value.op.op2->ts.type = BT_LOGICAL; 1417 block->expr1->value.op.op2->ts.kind = gfc_default_logical_kind; 1418 block->expr1->value.op.op2->expr_type = EXPR_OP; 1419 block->expr1->value.op.op2->where = gfc_current_locus; 1420 block->expr1->value.op.op2->value.op.op = INTRINSIC_EQ; 1421 block->expr1->value.op.op2->value.op.op1 = 1422 gfc_get_int_expr (gfc_index_integer_kind, NULL, 0); 1423 block->expr1->value.op.op2->value.op.op2 = gfc_copy_expr (size_expr); 1424 1425 /* IF body: call final subroutine. */ 1426 block->next = gfc_get_code (EXEC_CALL); 1427 block->next->symtree = fini->proc_tree; 1428 block->next->resolved_sym = fini->proc_tree->n.sym; 1429 block->next->ext.actual = gfc_get_actual_arglist (); 1430 block->next->ext.actual->expr = gfc_lval_expr_from_sym (array); 1431 block->next->ext.actual->next = gfc_get_actual_arglist (); 1432 block->next->ext.actual->next->expr = gfc_copy_expr (size_expr); 1433 1434 /* ELSE. */ 1435 1436 block->block = gfc_get_code (EXEC_IF); 1437 block = block->block; 1438 1439 /* BLOCK ... END BLOCK. */ 1440 block->next = gfc_get_code (EXEC_BLOCK); 1441 block = block->next; 1442 1443 ns = gfc_build_block_ns (sub_ns); 1444 block->ext.block.ns = ns; 1445 block->ext.block.assoc = NULL; 1446 1447 gfc_get_symbol ("ptr2", ns, &ptr2); 1448 ptr2->ts.type = BT_DERIVED; 1449 ptr2->ts.u.derived = array->ts.u.derived; 1450 ptr2->attr.flavor = FL_VARIABLE; 1451 ptr2->attr.pointer = 1; 1452 ptr2->attr.artificial = 1; 1453 gfc_set_sym_referenced (ptr2); 1454 gfc_commit_symbol (ptr2); 1455 1456 gfc_get_symbol ("tmp_array", ns, &tmp_array); 1457 tmp_array->ts.type = BT_DERIVED; 1458 tmp_array->ts.u.derived = array->ts.u.derived; 1459 tmp_array->attr.flavor = FL_VARIABLE; 1460 tmp_array->attr.dimension = 1; 1461 tmp_array->attr.artificial = 1; 1462 tmp_array->as = gfc_get_array_spec(); 1463 tmp_array->attr.intent = INTENT_INOUT; 1464 tmp_array->as->type = AS_EXPLICIT; 1465 tmp_array->as->rank = fini->proc_tree->n.sym->formal->sym->as->rank; 1466 1467 for (i = 0; i < tmp_array->as->rank; i++) 1468 { 1469 gfc_expr *shape_expr; 1470 tmp_array->as->lower[i] = gfc_get_int_expr (gfc_default_integer_kind, 1471 NULL, 1); 1472 /* SIZE (array, dim=i+1, kind=gfc_index_integer_kind). */ 1473 shape_expr 1474 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size", 1475 gfc_current_locus, 3, 1476 gfc_lval_expr_from_sym (array), 1477 gfc_get_int_expr (gfc_default_integer_kind, 1478 NULL, i+1), 1479 gfc_get_int_expr (gfc_default_integer_kind, 1480 NULL, 1481 gfc_index_integer_kind)); 1482 shape_expr->ts.kind = gfc_index_integer_kind; 1483 tmp_array->as->upper[i] = shape_expr; 1484 } 1485 gfc_set_sym_referenced (tmp_array); 1486 gfc_commit_symbol (tmp_array); 1487 1488 /* Create loop. */ 1489 iter = gfc_get_iterator (); 1490 iter->var = gfc_lval_expr_from_sym (idx); 1491 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0); 1492 iter->end = gfc_lval_expr_from_sym (nelem); 1493 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1); 1494 1495 block = gfc_get_code (EXEC_DO); 1496 ns->code = block; 1497 block->ext.iterator = iter; 1498 block->block = gfc_get_code (EXEC_DO); 1499 1500 /* Offset calculation for the new array: idx * size of type (in bytes). */ 1501 offset2 = gfc_get_expr (); 1502 offset2->expr_type = EXPR_OP; 1503 offset2->where = gfc_current_locus; 1504 offset2->value.op.op = INTRINSIC_TIMES; 1505 offset2->value.op.op1 = gfc_lval_expr_from_sym (idx); 1506 offset2->value.op.op2 = gfc_copy_expr (size_expr); 1507 offset2->ts = byte_stride->ts; 1508 1509 /* Offset calculation of "array". */ 1510 block2 = finalization_get_offset (idx, idx2, offset, strides, sizes, 1511 byte_stride, rank, block->block, sub_ns); 1512 1513 /* Create code for 1514 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr) 1515 + idx * stride, c_ptr), ptr). */ 1516 block2->next = finalization_scalarizer (array, ptr, 1517 gfc_lval_expr_from_sym (offset), 1518 sub_ns); 1519 block2 = block2->next; 1520 block2->next = finalization_scalarizer (tmp_array, ptr2, offset2, sub_ns); 1521 block2 = block2->next; 1522 1523 /* ptr2 = ptr. */ 1524 block2->next = gfc_get_code (EXEC_ASSIGN); 1525 block2 = block2->next; 1526 block2->expr1 = gfc_lval_expr_from_sym (ptr2); 1527 block2->expr2 = gfc_lval_expr_from_sym (ptr); 1528 1529 /* Call now the user's final subroutine. */ 1530 block->next = gfc_get_code (EXEC_CALL); 1531 block = block->next; 1532 block->symtree = fini->proc_tree; 1533 block->resolved_sym = fini->proc_tree->n.sym; 1534 block->ext.actual = gfc_get_actual_arglist (); 1535 block->ext.actual->expr = gfc_lval_expr_from_sym (tmp_array); 1536 1537 if (fini->proc_tree->n.sym->formal->sym->attr.intent == INTENT_IN) 1538 return; 1539 1540 /* Copy back. */ 1541 1542 /* Loop. */ 1543 iter = gfc_get_iterator (); 1544 iter->var = gfc_lval_expr_from_sym (idx); 1545 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0); 1546 iter->end = gfc_lval_expr_from_sym (nelem); 1547 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1); 1548 1549 block->next = gfc_get_code (EXEC_DO); 1550 block = block->next; 1551 block->ext.iterator = iter; 1552 block->block = gfc_get_code (EXEC_DO); 1553 1554 /* Offset calculation of "array". */ 1555 block2 = finalization_get_offset (idx, idx2, offset, strides, sizes, 1556 byte_stride, rank, block->block, sub_ns); 1557 1558 /* Create code for 1559 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr) 1560 + offset, c_ptr), ptr). */ 1561 block2->next = finalization_scalarizer (array, ptr, 1562 gfc_lval_expr_from_sym (offset), 1563 sub_ns); 1564 block2 = block2->next; 1565 block2->next = finalization_scalarizer (tmp_array, ptr2, 1566 gfc_copy_expr (offset2), sub_ns); 1567 block2 = block2->next; 1568 1569 /* ptr = ptr2. */ 1570 block2->next = gfc_get_code (EXEC_ASSIGN); 1571 block2->next->expr1 = gfc_lval_expr_from_sym (ptr); 1572 block2->next->expr2 = gfc_lval_expr_from_sym (ptr2); 1573 } 1574 1575 1576 /* Generate the finalization/polymorphic freeing wrapper subroutine for the 1577 derived type "derived". The function first calls the approriate FINAL 1578 subroutine, then it DEALLOCATEs (finalizes/frees) the allocatable 1579 components (but not the inherited ones). Last, it calls the wrapper 1580 subroutine of the parent. The generated wrapper procedure takes as argument 1581 an assumed-rank array. 1582 If neither allocatable components nor FINAL subroutines exists, the vtab 1583 will contain a NULL pointer. 1584 The generated function has the form 1585 _final(assumed-rank array, stride, skip_corarray) 1586 where the array has to be contiguous (except of the lowest dimension). The 1587 stride (in bytes) is used to allow different sizes for ancestor types by 1588 skipping over the additionally added components in the scalarizer. If 1589 "fini_coarray" is false, coarray components are not finalized to allow for 1590 the correct semantic with intrinsic assignment. */ 1591 1592 static void 1593 generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns, 1594 const char *tname, gfc_component *vtab_final) 1595 { 1596 gfc_symbol *final, *array, *fini_coarray, *byte_stride, *sizes, *strides; 1597 gfc_symbol *ptr = NULL, *idx, *idx2, *is_contiguous, *offset, *nelem; 1598 gfc_component *comp; 1599 gfc_namespace *sub_ns; 1600 gfc_code *last_code, *block; 1601 char *name; 1602 bool finalizable_comp = false; 1603 bool expr_null_wrapper = false; 1604 gfc_expr *ancestor_wrapper = NULL, *rank; 1605 gfc_iterator *iter; 1606 1607 if (derived->attr.unlimited_polymorphic) 1608 { 1609 vtab_final->initializer = gfc_get_null_expr (NULL); 1610 return; 1611 } 1612 1613 /* Search for the ancestor's finalizers. */ 1614 if (derived->attr.extension && derived->components 1615 && (!derived->components->ts.u.derived->attr.abstract 1616 || has_finalizer_component (derived))) 1617 { 1618 gfc_symbol *vtab; 1619 gfc_component *comp; 1620 1621 vtab = gfc_find_derived_vtab (derived->components->ts.u.derived); 1622 for (comp = vtab->ts.u.derived->components; comp; comp = comp->next) 1623 if (comp->name[0] == '_' && comp->name[1] == 'f') 1624 { 1625 ancestor_wrapper = comp->initializer; 1626 break; 1627 } 1628 } 1629 1630 /* No wrapper of the ancestor and no own FINAL subroutines and allocatable 1631 components: Return a NULL() expression; we defer this a bit to have 1632 an interface declaration. */ 1633 if ((!ancestor_wrapper || ancestor_wrapper->expr_type == EXPR_NULL) 1634 && !derived->attr.alloc_comp 1635 && (!derived->f2k_derived || !derived->f2k_derived->finalizers) 1636 && !has_finalizer_component (derived)) 1637 expr_null_wrapper = true; 1638 else 1639 /* Check whether there are new allocatable components. */ 1640 for (comp = derived->components; comp; comp = comp->next) 1641 { 1642 if (comp == derived->components && derived->attr.extension 1643 && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL) 1644 continue; 1645 1646 finalizable_comp |= comp_is_finalizable (comp); 1647 } 1648 1649 /* If there is no new finalizer and no new allocatable, return with 1650 an expr to the ancestor's one. */ 1651 if (!expr_null_wrapper && !finalizable_comp 1652 && (!derived->f2k_derived || !derived->f2k_derived->finalizers)) 1653 { 1654 gcc_assert (ancestor_wrapper && ancestor_wrapper->ref == NULL 1655 && ancestor_wrapper->expr_type == EXPR_VARIABLE); 1656 vtab_final->initializer = gfc_copy_expr (ancestor_wrapper); 1657 vtab_final->ts.interface = vtab_final->initializer->symtree->n.sym; 1658 return; 1659 } 1660 1661 /* We now create a wrapper, which does the following: 1662 1. Call the suitable finalization subroutine for this type 1663 2. Loop over all noninherited allocatable components and noninherited 1664 components with allocatable components and DEALLOCATE those; this will 1665 take care of finalizers, coarray deregistering and allocatable 1666 nested components. 1667 3. Call the ancestor's finalizer. */ 1668 1669 /* Declare the wrapper function; it takes an assumed-rank array 1670 and a VALUE logical as arguments. */ 1671 1672 /* Set up the namespace. */ 1673 sub_ns = gfc_get_namespace (ns, 0); 1674 sub_ns->sibling = ns->contained; 1675 if (!expr_null_wrapper) 1676 ns->contained = sub_ns; 1677 sub_ns->resolved = 1; 1678 1679 /* Set up the procedure symbol. */ 1680 name = xasprintf ("__final_%s", tname); 1681 gfc_get_symbol (name, sub_ns, &final); 1682 sub_ns->proc_name = final; 1683 final->attr.flavor = FL_PROCEDURE; 1684 final->attr.function = 1; 1685 final->attr.pure = 0; 1686 final->attr.recursive = 1; 1687 final->result = final; 1688 final->ts.type = BT_INTEGER; 1689 final->ts.kind = 4; 1690 final->attr.artificial = 1; 1691 final->attr.always_explicit = 1; 1692 final->attr.if_source = expr_null_wrapper ? IFSRC_IFBODY : IFSRC_DECL; 1693 if (ns->proc_name->attr.flavor == FL_MODULE) 1694 final->module = ns->proc_name->name; 1695 gfc_set_sym_referenced (final); 1696 gfc_commit_symbol (final); 1697 1698 /* Set up formal argument. */ 1699 gfc_get_symbol ("array", sub_ns, &array); 1700 array->ts.type = BT_DERIVED; 1701 array->ts.u.derived = derived; 1702 array->attr.flavor = FL_VARIABLE; 1703 array->attr.dummy = 1; 1704 array->attr.contiguous = 1; 1705 array->attr.dimension = 1; 1706 array->attr.artificial = 1; 1707 array->as = gfc_get_array_spec(); 1708 array->as->type = AS_ASSUMED_RANK; 1709 array->as->rank = -1; 1710 array->attr.intent = INTENT_INOUT; 1711 gfc_set_sym_referenced (array); 1712 final->formal = gfc_get_formal_arglist (); 1713 final->formal->sym = array; 1714 gfc_commit_symbol (array); 1715 1716 /* Set up formal argument. */ 1717 gfc_get_symbol ("byte_stride", sub_ns, &byte_stride); 1718 byte_stride->ts.type = BT_INTEGER; 1719 byte_stride->ts.kind = gfc_index_integer_kind; 1720 byte_stride->attr.flavor = FL_VARIABLE; 1721 byte_stride->attr.dummy = 1; 1722 byte_stride->attr.value = 1; 1723 byte_stride->attr.artificial = 1; 1724 gfc_set_sym_referenced (byte_stride); 1725 final->formal->next = gfc_get_formal_arglist (); 1726 final->formal->next->sym = byte_stride; 1727 gfc_commit_symbol (byte_stride); 1728 1729 /* Set up formal argument. */ 1730 gfc_get_symbol ("fini_coarray", sub_ns, &fini_coarray); 1731 fini_coarray->ts.type = BT_LOGICAL; 1732 fini_coarray->ts.kind = 1; 1733 fini_coarray->attr.flavor = FL_VARIABLE; 1734 fini_coarray->attr.dummy = 1; 1735 fini_coarray->attr.value = 1; 1736 fini_coarray->attr.artificial = 1; 1737 gfc_set_sym_referenced (fini_coarray); 1738 final->formal->next->next = gfc_get_formal_arglist (); 1739 final->formal->next->next->sym = fini_coarray; 1740 gfc_commit_symbol (fini_coarray); 1741 1742 /* Return with a NULL() expression but with an interface which has 1743 the formal arguments. */ 1744 if (expr_null_wrapper) 1745 { 1746 vtab_final->initializer = gfc_get_null_expr (NULL); 1747 vtab_final->ts.interface = final; 1748 return; 1749 } 1750 1751 /* Local variables. */ 1752 1753 gfc_get_symbol ("idx", sub_ns, &idx); 1754 idx->ts.type = BT_INTEGER; 1755 idx->ts.kind = gfc_index_integer_kind; 1756 idx->attr.flavor = FL_VARIABLE; 1757 idx->attr.artificial = 1; 1758 gfc_set_sym_referenced (idx); 1759 gfc_commit_symbol (idx); 1760 1761 gfc_get_symbol ("idx2", sub_ns, &idx2); 1762 idx2->ts.type = BT_INTEGER; 1763 idx2->ts.kind = gfc_index_integer_kind; 1764 idx2->attr.flavor = FL_VARIABLE; 1765 idx2->attr.artificial = 1; 1766 gfc_set_sym_referenced (idx2); 1767 gfc_commit_symbol (idx2); 1768 1769 gfc_get_symbol ("offset", sub_ns, &offset); 1770 offset->ts.type = BT_INTEGER; 1771 offset->ts.kind = gfc_index_integer_kind; 1772 offset->attr.flavor = FL_VARIABLE; 1773 offset->attr.artificial = 1; 1774 gfc_set_sym_referenced (offset); 1775 gfc_commit_symbol (offset); 1776 1777 /* Create RANK expression. */ 1778 rank = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_RANK, "rank", 1779 gfc_current_locus, 1, 1780 gfc_lval_expr_from_sym (array)); 1781 if (rank->ts.kind != idx->ts.kind) 1782 gfc_convert_type_warn (rank, &idx->ts, 2, 0); 1783 1784 /* Create is_contiguous variable. */ 1785 gfc_get_symbol ("is_contiguous", sub_ns, &is_contiguous); 1786 is_contiguous->ts.type = BT_LOGICAL; 1787 is_contiguous->ts.kind = gfc_default_logical_kind; 1788 is_contiguous->attr.flavor = FL_VARIABLE; 1789 is_contiguous->attr.artificial = 1; 1790 gfc_set_sym_referenced (is_contiguous); 1791 gfc_commit_symbol (is_contiguous); 1792 1793 /* Create "sizes(0..rank)" variable, which contains the multiplied 1794 up extent of the dimensions, i.e. sizes(0) = 1, sizes(1) = extent(dim=1), 1795 sizes(2) = sizes(1) * extent(dim=2) etc. */ 1796 gfc_get_symbol ("sizes", sub_ns, &sizes); 1797 sizes->ts.type = BT_INTEGER; 1798 sizes->ts.kind = gfc_index_integer_kind; 1799 sizes->attr.flavor = FL_VARIABLE; 1800 sizes->attr.dimension = 1; 1801 sizes->attr.artificial = 1; 1802 sizes->as = gfc_get_array_spec(); 1803 sizes->attr.intent = INTENT_INOUT; 1804 sizes->as->type = AS_EXPLICIT; 1805 sizes->as->rank = 1; 1806 sizes->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0); 1807 sizes->as->upper[0] = gfc_copy_expr (rank); 1808 gfc_set_sym_referenced (sizes); 1809 gfc_commit_symbol (sizes); 1810 1811 /* Create "strides(1..rank)" variable, which contains the strides per 1812 dimension. */ 1813 gfc_get_symbol ("strides", sub_ns, &strides); 1814 strides->ts.type = BT_INTEGER; 1815 strides->ts.kind = gfc_index_integer_kind; 1816 strides->attr.flavor = FL_VARIABLE; 1817 strides->attr.dimension = 1; 1818 strides->attr.artificial = 1; 1819 strides->as = gfc_get_array_spec(); 1820 strides->attr.intent = INTENT_INOUT; 1821 strides->as->type = AS_EXPLICIT; 1822 strides->as->rank = 1; 1823 strides->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1); 1824 strides->as->upper[0] = gfc_copy_expr (rank); 1825 gfc_set_sym_referenced (strides); 1826 gfc_commit_symbol (strides); 1827 1828 1829 /* Set return value to 0. */ 1830 last_code = gfc_get_code (EXEC_ASSIGN); 1831 last_code->expr1 = gfc_lval_expr_from_sym (final); 1832 last_code->expr2 = gfc_get_int_expr (4, NULL, 0); 1833 sub_ns->code = last_code; 1834 1835 /* Set: is_contiguous = .true. */ 1836 last_code->next = gfc_get_code (EXEC_ASSIGN); 1837 last_code = last_code->next; 1838 last_code->expr1 = gfc_lval_expr_from_sym (is_contiguous); 1839 last_code->expr2 = gfc_get_logical_expr (gfc_default_logical_kind, 1840 &gfc_current_locus, true); 1841 1842 /* Set: sizes(0) = 1. */ 1843 last_code->next = gfc_get_code (EXEC_ASSIGN); 1844 last_code = last_code->next; 1845 last_code->expr1 = gfc_lval_expr_from_sym (sizes); 1846 last_code->expr1->ref = gfc_get_ref (); 1847 last_code->expr1->ref->type = REF_ARRAY; 1848 last_code->expr1->ref->u.ar.type = AR_ELEMENT; 1849 last_code->expr1->ref->u.ar.dimen = 1; 1850 last_code->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT; 1851 last_code->expr1->ref->u.ar.start[0] 1852 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0); 1853 last_code->expr1->ref->u.ar.as = sizes->as; 1854 last_code->expr2 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1); 1855 1856 /* Create: 1857 DO idx = 1, rank 1858 strides(idx) = _F._stride (array, dim=idx) 1859 sizes(idx) = sizes(i-1) * size(array, dim=idx, kind=index_kind) 1860 if (strides (idx) /= sizes(i-1)) is_contiguous = .false. 1861 END DO. */ 1862 1863 /* Create loop. */ 1864 iter = gfc_get_iterator (); 1865 iter->var = gfc_lval_expr_from_sym (idx); 1866 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1); 1867 iter->end = gfc_copy_expr (rank); 1868 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1); 1869 last_code->next = gfc_get_code (EXEC_DO); 1870 last_code = last_code->next; 1871 last_code->ext.iterator = iter; 1872 last_code->block = gfc_get_code (EXEC_DO); 1873 1874 /* strides(idx) = _F._stride(array,dim=idx). */ 1875 last_code->block->next = gfc_get_code (EXEC_ASSIGN); 1876 block = last_code->block->next; 1877 1878 block->expr1 = gfc_lval_expr_from_sym (strides); 1879 block->expr1->ref = gfc_get_ref (); 1880 block->expr1->ref->type = REF_ARRAY; 1881 block->expr1->ref->u.ar.type = AR_ELEMENT; 1882 block->expr1->ref->u.ar.dimen = 1; 1883 block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT; 1884 block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx); 1885 block->expr1->ref->u.ar.as = strides->as; 1886 1887 block->expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STRIDE, "stride", 1888 gfc_current_locus, 2, 1889 gfc_lval_expr_from_sym (array), 1890 gfc_lval_expr_from_sym (idx)); 1891 1892 /* sizes(idx) = sizes(idx-1) * size(array,dim=idx, kind=index_kind). */ 1893 block->next = gfc_get_code (EXEC_ASSIGN); 1894 block = block->next; 1895 1896 /* sizes(idx) = ... */ 1897 block->expr1 = gfc_lval_expr_from_sym (sizes); 1898 block->expr1->ref = gfc_get_ref (); 1899 block->expr1->ref->type = REF_ARRAY; 1900 block->expr1->ref->u.ar.type = AR_ELEMENT; 1901 block->expr1->ref->u.ar.dimen = 1; 1902 block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT; 1903 block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx); 1904 block->expr1->ref->u.ar.as = sizes->as; 1905 1906 block->expr2 = gfc_get_expr (); 1907 block->expr2->expr_type = EXPR_OP; 1908 block->expr2->value.op.op = INTRINSIC_TIMES; 1909 block->expr2->where = gfc_current_locus; 1910 1911 /* sizes(idx-1). */ 1912 block->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes); 1913 block->expr2->value.op.op1->ref = gfc_get_ref (); 1914 block->expr2->value.op.op1->ref->type = REF_ARRAY; 1915 block->expr2->value.op.op1->ref->u.ar.as = sizes->as; 1916 block->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT; 1917 block->expr2->value.op.op1->ref->u.ar.dimen = 1; 1918 block->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT; 1919 block->expr2->value.op.op1->ref->u.ar.start[0] = gfc_get_expr (); 1920 block->expr2->value.op.op1->ref->u.ar.start[0]->expr_type = EXPR_OP; 1921 block->expr2->value.op.op1->ref->u.ar.start[0]->where = gfc_current_locus; 1922 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS; 1923 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1 1924 = gfc_lval_expr_from_sym (idx); 1925 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op2 1926 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1); 1927 block->expr2->value.op.op1->ref->u.ar.start[0]->ts 1928 = block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1->ts; 1929 1930 /* size(array, dim=idx, kind=index_kind). */ 1931 block->expr2->value.op.op2 1932 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size", 1933 gfc_current_locus, 3, 1934 gfc_lval_expr_from_sym (array), 1935 gfc_lval_expr_from_sym (idx), 1936 gfc_get_int_expr (gfc_index_integer_kind, 1937 NULL, 1938 gfc_index_integer_kind)); 1939 block->expr2->value.op.op2->ts.kind = gfc_index_integer_kind; 1940 block->expr2->ts = idx->ts; 1941 1942 /* if (strides (idx) /= sizes(idx-1)) is_contiguous = .false. */ 1943 block->next = gfc_get_code (EXEC_IF); 1944 block = block->next; 1945 1946 block->block = gfc_get_code (EXEC_IF); 1947 block = block->block; 1948 1949 /* if condition: strides(idx) /= sizes(idx-1). */ 1950 block->expr1 = gfc_get_expr (); 1951 block->expr1->ts.type = BT_LOGICAL; 1952 block->expr1->ts.kind = gfc_default_logical_kind; 1953 block->expr1->expr_type = EXPR_OP; 1954 block->expr1->where = gfc_current_locus; 1955 block->expr1->value.op.op = INTRINSIC_NE; 1956 1957 block->expr1->value.op.op1 = gfc_lval_expr_from_sym (strides); 1958 block->expr1->value.op.op1->ref = gfc_get_ref (); 1959 block->expr1->value.op.op1->ref->type = REF_ARRAY; 1960 block->expr1->value.op.op1->ref->u.ar.type = AR_ELEMENT; 1961 block->expr1->value.op.op1->ref->u.ar.dimen = 1; 1962 block->expr1->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT; 1963 block->expr1->value.op.op1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx); 1964 block->expr1->value.op.op1->ref->u.ar.as = strides->as; 1965 1966 block->expr1->value.op.op2 = gfc_lval_expr_from_sym (sizes); 1967 block->expr1->value.op.op2->ref = gfc_get_ref (); 1968 block->expr1->value.op.op2->ref->type = REF_ARRAY; 1969 block->expr1->value.op.op2->ref->u.ar.as = sizes->as; 1970 block->expr1->value.op.op2->ref->u.ar.type = AR_ELEMENT; 1971 block->expr1->value.op.op2->ref->u.ar.dimen = 1; 1972 block->expr1->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT; 1973 block->expr1->value.op.op2->ref->u.ar.start[0] = gfc_get_expr (); 1974 block->expr1->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP; 1975 block->expr1->value.op.op2->ref->u.ar.start[0]->where = gfc_current_locus; 1976 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS; 1977 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1 1978 = gfc_lval_expr_from_sym (idx); 1979 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op2 1980 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1); 1981 block->expr1->value.op.op2->ref->u.ar.start[0]->ts 1982 = block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts; 1983 1984 /* if body: is_contiguous = .false. */ 1985 block->next = gfc_get_code (EXEC_ASSIGN); 1986 block = block->next; 1987 block->expr1 = gfc_lval_expr_from_sym (is_contiguous); 1988 block->expr2 = gfc_get_logical_expr (gfc_default_logical_kind, 1989 &gfc_current_locus, false); 1990 1991 /* Obtain the size (number of elements) of "array" MINUS ONE, 1992 which is used in the scalarization. */ 1993 gfc_get_symbol ("nelem", sub_ns, &nelem); 1994 nelem->ts.type = BT_INTEGER; 1995 nelem->ts.kind = gfc_index_integer_kind; 1996 nelem->attr.flavor = FL_VARIABLE; 1997 nelem->attr.artificial = 1; 1998 gfc_set_sym_referenced (nelem); 1999 gfc_commit_symbol (nelem); 2000 2001 /* nelem = sizes (rank) - 1. */ 2002 last_code->next = gfc_get_code (EXEC_ASSIGN); 2003 last_code = last_code->next; 2004 2005 last_code->expr1 = gfc_lval_expr_from_sym (nelem); 2006 2007 last_code->expr2 = gfc_get_expr (); 2008 last_code->expr2->expr_type = EXPR_OP; 2009 last_code->expr2->value.op.op = INTRINSIC_MINUS; 2010 last_code->expr2->value.op.op2 2011 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1); 2012 last_code->expr2->ts = last_code->expr2->value.op.op2->ts; 2013 last_code->expr2->where = gfc_current_locus; 2014 2015 last_code->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes); 2016 last_code->expr2->value.op.op1->ref = gfc_get_ref (); 2017 last_code->expr2->value.op.op1->ref->type = REF_ARRAY; 2018 last_code->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT; 2019 last_code->expr2->value.op.op1->ref->u.ar.dimen = 1; 2020 last_code->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT; 2021 last_code->expr2->value.op.op1->ref->u.ar.start[0] = gfc_copy_expr (rank); 2022 last_code->expr2->value.op.op1->ref->u.ar.as = sizes->as; 2023 2024 /* Call final subroutines. We now generate code like: 2025 use iso_c_binding 2026 integer, pointer :: ptr 2027 type(c_ptr) :: cptr 2028 integer(c_intptr_t) :: i, addr 2029 2030 select case (rank (array)) 2031 case (3) 2032 ! If needed, the array is packed 2033 call final_rank3 (array) 2034 case default: 2035 do i = 0, size (array)-1 2036 addr = transfer (c_loc (array), addr) + i * stride 2037 call c_f_pointer (transfer (addr, cptr), ptr) 2038 call elemental_final (ptr) 2039 end do 2040 end select */ 2041 2042 if (derived->f2k_derived && derived->f2k_derived->finalizers) 2043 { 2044 gfc_finalizer *fini, *fini_elem = NULL; 2045 2046 gfc_get_symbol ("ptr1", sub_ns, &ptr); 2047 ptr->ts.type = BT_DERIVED; 2048 ptr->ts.u.derived = derived; 2049 ptr->attr.flavor = FL_VARIABLE; 2050 ptr->attr.pointer = 1; 2051 ptr->attr.artificial = 1; 2052 gfc_set_sym_referenced (ptr); 2053 gfc_commit_symbol (ptr); 2054 2055 /* SELECT CASE (RANK (array)). */ 2056 last_code->next = gfc_get_code (EXEC_SELECT); 2057 last_code = last_code->next; 2058 last_code->expr1 = gfc_copy_expr (rank); 2059 block = NULL; 2060 2061 for (fini = derived->f2k_derived->finalizers; fini; fini = fini->next) 2062 { 2063 gcc_assert (fini->proc_tree); /* Should have been set in gfc_resolve_finalizers. */ 2064 if (fini->proc_tree->n.sym->attr.elemental) 2065 { 2066 fini_elem = fini; 2067 continue; 2068 } 2069 2070 /* CASE (fini_rank). */ 2071 if (block) 2072 { 2073 block->block = gfc_get_code (EXEC_SELECT); 2074 block = block->block; 2075 } 2076 else 2077 { 2078 block = gfc_get_code (EXEC_SELECT); 2079 last_code->block = block; 2080 } 2081 block->ext.block.case_list = gfc_get_case (); 2082 block->ext.block.case_list->where = gfc_current_locus; 2083 if (fini->proc_tree->n.sym->formal->sym->attr.dimension) 2084 block->ext.block.case_list->low 2085 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 2086 fini->proc_tree->n.sym->formal->sym->as->rank); 2087 else 2088 block->ext.block.case_list->low 2089 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0); 2090 block->ext.block.case_list->high 2091 = gfc_copy_expr (block->ext.block.case_list->low); 2092 2093 /* CALL fini_rank (array) - possibly with packing. */ 2094 if (fini->proc_tree->n.sym->formal->sym->attr.dimension) 2095 finalizer_insert_packed_call (block, fini, array, byte_stride, 2096 idx, ptr, nelem, strides, 2097 sizes, idx2, offset, is_contiguous, 2098 rank, sub_ns); 2099 else 2100 { 2101 block->next = gfc_get_code (EXEC_CALL); 2102 block->next->symtree = fini->proc_tree; 2103 block->next->resolved_sym = fini->proc_tree->n.sym; 2104 block->next->ext.actual = gfc_get_actual_arglist (); 2105 block->next->ext.actual->expr = gfc_lval_expr_from_sym (array); 2106 } 2107 } 2108 2109 /* Elemental call - scalarized. */ 2110 if (fini_elem) 2111 { 2112 /* CASE DEFAULT. */ 2113 if (block) 2114 { 2115 block->block = gfc_get_code (EXEC_SELECT); 2116 block = block->block; 2117 } 2118 else 2119 { 2120 block = gfc_get_code (EXEC_SELECT); 2121 last_code->block = block; 2122 } 2123 block->ext.block.case_list = gfc_get_case (); 2124 2125 /* Create loop. */ 2126 iter = gfc_get_iterator (); 2127 iter->var = gfc_lval_expr_from_sym (idx); 2128 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0); 2129 iter->end = gfc_lval_expr_from_sym (nelem); 2130 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1); 2131 block->next = gfc_get_code (EXEC_DO); 2132 block = block->next; 2133 block->ext.iterator = iter; 2134 block->block = gfc_get_code (EXEC_DO); 2135 2136 /* Offset calculation. */ 2137 block = finalization_get_offset (idx, idx2, offset, strides, sizes, 2138 byte_stride, rank, block->block, 2139 sub_ns); 2140 2141 /* Create code for 2142 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr) 2143 + offset, c_ptr), ptr). */ 2144 block->next 2145 = finalization_scalarizer (array, ptr, 2146 gfc_lval_expr_from_sym (offset), 2147 sub_ns); 2148 block = block->next; 2149 2150 /* CALL final_elemental (array). */ 2151 block->next = gfc_get_code (EXEC_CALL); 2152 block = block->next; 2153 block->symtree = fini_elem->proc_tree; 2154 block->resolved_sym = fini_elem->proc_sym; 2155 block->ext.actual = gfc_get_actual_arglist (); 2156 block->ext.actual->expr = gfc_lval_expr_from_sym (ptr); 2157 } 2158 } 2159 2160 /* Finalize and deallocate allocatable components. The same manual 2161 scalarization is used as above. */ 2162 2163 if (finalizable_comp) 2164 { 2165 gfc_symbol *stat; 2166 gfc_code *block = NULL; 2167 2168 if (!ptr) 2169 { 2170 gfc_get_symbol ("ptr2", sub_ns, &ptr); 2171 ptr->ts.type = BT_DERIVED; 2172 ptr->ts.u.derived = derived; 2173 ptr->attr.flavor = FL_VARIABLE; 2174 ptr->attr.pointer = 1; 2175 ptr->attr.artificial = 1; 2176 gfc_set_sym_referenced (ptr); 2177 gfc_commit_symbol (ptr); 2178 } 2179 2180 gfc_get_symbol ("ignore", sub_ns, &stat); 2181 stat->attr.flavor = FL_VARIABLE; 2182 stat->attr.artificial = 1; 2183 stat->ts.type = BT_INTEGER; 2184 stat->ts.kind = gfc_default_integer_kind; 2185 gfc_set_sym_referenced (stat); 2186 gfc_commit_symbol (stat); 2187 2188 /* Create loop. */ 2189 iter = gfc_get_iterator (); 2190 iter->var = gfc_lval_expr_from_sym (idx); 2191 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0); 2192 iter->end = gfc_lval_expr_from_sym (nelem); 2193 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1); 2194 last_code->next = gfc_get_code (EXEC_DO); 2195 last_code = last_code->next; 2196 last_code->ext.iterator = iter; 2197 last_code->block = gfc_get_code (EXEC_DO); 2198 2199 /* Offset calculation. */ 2200 block = finalization_get_offset (idx, idx2, offset, strides, sizes, 2201 byte_stride, rank, last_code->block, 2202 sub_ns); 2203 2204 /* Create code for 2205 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr) 2206 + idx * stride, c_ptr), ptr). */ 2207 block->next = finalization_scalarizer (array, ptr, 2208 gfc_lval_expr_from_sym(offset), 2209 sub_ns); 2210 block = block->next; 2211 2212 for (comp = derived->components; comp; comp = comp->next) 2213 { 2214 if (comp == derived->components && derived->attr.extension 2215 && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL) 2216 continue; 2217 2218 finalize_component (gfc_lval_expr_from_sym (ptr), derived, comp, 2219 stat, fini_coarray, &block, sub_ns); 2220 if (!last_code->block->next) 2221 last_code->block->next = block; 2222 } 2223 2224 } 2225 2226 /* Call the finalizer of the ancestor. */ 2227 if (ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL) 2228 { 2229 last_code->next = gfc_get_code (EXEC_CALL); 2230 last_code = last_code->next; 2231 last_code->symtree = ancestor_wrapper->symtree; 2232 last_code->resolved_sym = ancestor_wrapper->symtree->n.sym; 2233 2234 last_code->ext.actual = gfc_get_actual_arglist (); 2235 last_code->ext.actual->expr = gfc_lval_expr_from_sym (array); 2236 last_code->ext.actual->next = gfc_get_actual_arglist (); 2237 last_code->ext.actual->next->expr = gfc_lval_expr_from_sym (byte_stride); 2238 last_code->ext.actual->next->next = gfc_get_actual_arglist (); 2239 last_code->ext.actual->next->next->expr 2240 = gfc_lval_expr_from_sym (fini_coarray); 2241 } 2242 2243 gfc_free_expr (rank); 2244 vtab_final->initializer = gfc_lval_expr_from_sym (final); 2245 vtab_final->ts.interface = final; 2246 free (name); 2247 } 2248 2249 2250 /* Add procedure pointers for all type-bound procedures to a vtab. */ 2251 2252 static void 2253 add_procs_to_declared_vtab (gfc_symbol *derived, gfc_symbol *vtype) 2254 { 2255 gfc_symbol* super_type; 2256 2257 super_type = gfc_get_derived_super_type (derived); 2258 2259 if (super_type && (super_type != derived)) 2260 { 2261 /* Make sure that the PPCs appear in the same order as in the parent. */ 2262 copy_vtab_proc_comps (super_type, vtype); 2263 /* Only needed to get the PPC initializers right. */ 2264 add_procs_to_declared_vtab (super_type, vtype); 2265 } 2266 2267 if (derived->f2k_derived && derived->f2k_derived->tb_sym_root) 2268 add_procs_to_declared_vtab1 (derived->f2k_derived->tb_sym_root, vtype); 2269 2270 if (derived->f2k_derived && derived->f2k_derived->tb_uop_root) 2271 add_procs_to_declared_vtab1 (derived->f2k_derived->tb_uop_root, vtype); 2272 } 2273 2274 2275 /* Find or generate the symbol for a derived type's vtab. */ 2276 2277 gfc_symbol * 2278 gfc_find_derived_vtab (gfc_symbol *derived) 2279 { 2280 gfc_namespace *ns; 2281 gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL, *def_init = NULL; 2282 gfc_symbol *copy = NULL, *src = NULL, *dst = NULL; 2283 gfc_gsymbol *gsym = NULL; 2284 gfc_symbol *dealloc = NULL, *arg = NULL; 2285 2286 if (derived->attr.pdt_template) 2287 return NULL; 2288 2289 /* Find the top-level namespace. */ 2290 for (ns = gfc_current_ns; ns; ns = ns->parent) 2291 if (!ns->parent) 2292 break; 2293 2294 /* If the type is a class container, use the underlying derived type. */ 2295 if (!derived->attr.unlimited_polymorphic && derived->attr.is_class) 2296 derived = gfc_get_derived_super_type (derived); 2297 2298 if (!derived) 2299 return NULL; 2300 2301 if (!derived->name) 2302 return NULL; 2303 2304 /* Find the gsymbol for the module of use associated derived types. */ 2305 if ((derived->attr.use_assoc || derived->attr.used_in_submodule) 2306 && !derived->attr.vtype && !derived->attr.is_class) 2307 gsym = gfc_find_gsymbol (gfc_gsym_root, derived->module); 2308 else 2309 gsym = NULL; 2310 2311 /* Work in the gsymbol namespace if the top-level namespace is a module. 2312 This ensures that the vtable is unique, which is required since we use 2313 its address in SELECT TYPE. */ 2314 if (gsym && gsym->ns && ns && ns->proc_name 2315 && ns->proc_name->attr.flavor == FL_MODULE) 2316 ns = gsym->ns; 2317 2318 if (ns) 2319 { 2320 char tname[GFC_MAX_SYMBOL_LEN+1]; 2321 char *name; 2322 2323 get_unique_hashed_string (tname, derived); 2324 name = xasprintf ("__vtab_%s", tname); 2325 2326 /* Look for the vtab symbol in various namespaces. */ 2327 if (gsym && gsym->ns) 2328 { 2329 gfc_find_symbol (name, gsym->ns, 0, &vtab); 2330 if (vtab) 2331 ns = gsym->ns; 2332 } 2333 if (vtab == NULL) 2334 gfc_find_symbol (name, gfc_current_ns, 0, &vtab); 2335 if (vtab == NULL) 2336 gfc_find_symbol (name, ns, 0, &vtab); 2337 if (vtab == NULL) 2338 gfc_find_symbol (name, derived->ns, 0, &vtab); 2339 2340 if (vtab == NULL) 2341 { 2342 gfc_get_symbol (name, ns, &vtab); 2343 vtab->ts.type = BT_DERIVED; 2344 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL, 2345 &gfc_current_locus)) 2346 goto cleanup; 2347 vtab->attr.target = 1; 2348 vtab->attr.save = SAVE_IMPLICIT; 2349 vtab->attr.vtab = 1; 2350 vtab->attr.access = ACCESS_PUBLIC; 2351 gfc_set_sym_referenced (vtab); 2352 name = xasprintf ("__vtype_%s", tname); 2353 2354 gfc_find_symbol (name, ns, 0, &vtype); 2355 if (vtype == NULL) 2356 { 2357 gfc_component *c; 2358 gfc_symbol *parent = NULL, *parent_vtab = NULL; 2359 bool rdt = false; 2360 2361 /* Is this a derived type with recursive allocatable 2362 components? */ 2363 c = (derived->attr.unlimited_polymorphic 2364 || derived->attr.abstract) ? 2365 NULL : derived->components; 2366 for (; c; c= c->next) 2367 if (c->ts.type == BT_DERIVED 2368 && c->ts.u.derived == derived) 2369 { 2370 rdt = true; 2371 break; 2372 } 2373 2374 gfc_get_symbol (name, ns, &vtype); 2375 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL, 2376 &gfc_current_locus)) 2377 goto cleanup; 2378 vtype->attr.access = ACCESS_PUBLIC; 2379 vtype->attr.vtype = 1; 2380 gfc_set_sym_referenced (vtype); 2381 2382 /* Add component '_hash'. */ 2383 if (!gfc_add_component (vtype, "_hash", &c)) 2384 goto cleanup; 2385 c->ts.type = BT_INTEGER; 2386 c->ts.kind = 4; 2387 c->attr.access = ACCESS_PRIVATE; 2388 c->initializer = gfc_get_int_expr (gfc_default_integer_kind, 2389 NULL, derived->hash_value); 2390 2391 /* Add component '_size'. */ 2392 if (!gfc_add_component (vtype, "_size", &c)) 2393 goto cleanup; 2394 c->ts.type = BT_INTEGER; 2395 c->ts.kind = gfc_size_kind; 2396 c->attr.access = ACCESS_PRIVATE; 2397 /* Remember the derived type in ts.u.derived, 2398 so that the correct initializer can be set later on 2399 (in gfc_conv_structure). */ 2400 c->ts.u.derived = derived; 2401 c->initializer = gfc_get_int_expr (gfc_size_kind, 2402 NULL, 0); 2403 2404 /* Add component _extends. */ 2405 if (!gfc_add_component (vtype, "_extends", &c)) 2406 goto cleanup; 2407 c->attr.pointer = 1; 2408 c->attr.access = ACCESS_PRIVATE; 2409 if (!derived->attr.unlimited_polymorphic) 2410 parent = gfc_get_derived_super_type (derived); 2411 else 2412 parent = NULL; 2413 2414 if (parent) 2415 { 2416 parent_vtab = gfc_find_derived_vtab (parent); 2417 c->ts.type = BT_DERIVED; 2418 c->ts.u.derived = parent_vtab->ts.u.derived; 2419 c->initializer = gfc_get_expr (); 2420 c->initializer->expr_type = EXPR_VARIABLE; 2421 gfc_find_sym_tree (parent_vtab->name, parent_vtab->ns, 2422 0, &c->initializer->symtree); 2423 } 2424 else 2425 { 2426 c->ts.type = BT_DERIVED; 2427 c->ts.u.derived = vtype; 2428 c->initializer = gfc_get_null_expr (NULL); 2429 } 2430 2431 if (!derived->attr.unlimited_polymorphic 2432 && derived->components == NULL 2433 && !derived->attr.zero_comp) 2434 { 2435 /* At this point an error must have occurred. 2436 Prevent further errors on the vtype components. */ 2437 found_sym = vtab; 2438 goto have_vtype; 2439 } 2440 2441 /* Add component _def_init. */ 2442 if (!gfc_add_component (vtype, "_def_init", &c)) 2443 goto cleanup; 2444 c->attr.pointer = 1; 2445 c->attr.artificial = 1; 2446 c->attr.access = ACCESS_PRIVATE; 2447 c->ts.type = BT_DERIVED; 2448 c->ts.u.derived = derived; 2449 if (derived->attr.unlimited_polymorphic 2450 || derived->attr.abstract) 2451 c->initializer = gfc_get_null_expr (NULL); 2452 else 2453 { 2454 /* Construct default initialization variable. */ 2455 name = xasprintf ("__def_init_%s", tname); 2456 gfc_get_symbol (name, ns, &def_init); 2457 def_init->attr.target = 1; 2458 def_init->attr.artificial = 1; 2459 def_init->attr.save = SAVE_IMPLICIT; 2460 def_init->attr.access = ACCESS_PUBLIC; 2461 def_init->attr.flavor = FL_VARIABLE; 2462 gfc_set_sym_referenced (def_init); 2463 def_init->ts.type = BT_DERIVED; 2464 def_init->ts.u.derived = derived; 2465 def_init->value = gfc_default_initializer (&def_init->ts); 2466 2467 c->initializer = gfc_lval_expr_from_sym (def_init); 2468 } 2469 2470 /* Add component _copy. */ 2471 if (!gfc_add_component (vtype, "_copy", &c)) 2472 goto cleanup; 2473 c->attr.proc_pointer = 1; 2474 c->attr.access = ACCESS_PRIVATE; 2475 c->tb = XCNEW (gfc_typebound_proc); 2476 c->tb->ppc = 1; 2477 if (derived->attr.unlimited_polymorphic 2478 || derived->attr.abstract) 2479 c->initializer = gfc_get_null_expr (NULL); 2480 else 2481 { 2482 /* Set up namespace. */ 2483 gfc_namespace *sub_ns = gfc_get_namespace (ns, 0); 2484 sub_ns->sibling = ns->contained; 2485 ns->contained = sub_ns; 2486 sub_ns->resolved = 1; 2487 /* Set up procedure symbol. */ 2488 name = xasprintf ("__copy_%s", tname); 2489 gfc_get_symbol (name, sub_ns, ©); 2490 sub_ns->proc_name = copy; 2491 copy->attr.flavor = FL_PROCEDURE; 2492 copy->attr.subroutine = 1; 2493 copy->attr.pure = 1; 2494 copy->attr.artificial = 1; 2495 copy->attr.if_source = IFSRC_DECL; 2496 /* This is elemental so that arrays are automatically 2497 treated correctly by the scalarizer. */ 2498 copy->attr.elemental = 1; 2499 if (ns->proc_name->attr.flavor == FL_MODULE) 2500 copy->module = ns->proc_name->name; 2501 gfc_set_sym_referenced (copy); 2502 /* Set up formal arguments. */ 2503 gfc_get_symbol ("src", sub_ns, &src); 2504 src->ts.type = BT_DERIVED; 2505 src->ts.u.derived = derived; 2506 src->attr.flavor = FL_VARIABLE; 2507 src->attr.dummy = 1; 2508 src->attr.artificial = 1; 2509 src->attr.intent = INTENT_IN; 2510 gfc_set_sym_referenced (src); 2511 copy->formal = gfc_get_formal_arglist (); 2512 copy->formal->sym = src; 2513 gfc_get_symbol ("dst", sub_ns, &dst); 2514 dst->ts.type = BT_DERIVED; 2515 dst->ts.u.derived = derived; 2516 dst->attr.flavor = FL_VARIABLE; 2517 dst->attr.dummy = 1; 2518 dst->attr.artificial = 1; 2519 dst->attr.intent = INTENT_INOUT; 2520 gfc_set_sym_referenced (dst); 2521 copy->formal->next = gfc_get_formal_arglist (); 2522 copy->formal->next->sym = dst; 2523 /* Set up code. */ 2524 sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN); 2525 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst); 2526 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src); 2527 /* Set initializer. */ 2528 c->initializer = gfc_lval_expr_from_sym (copy); 2529 c->ts.interface = copy; 2530 } 2531 2532 /* Add component _final, which contains a procedure pointer to 2533 a wrapper which handles both the freeing of allocatable 2534 components and the calls to finalization subroutines. 2535 Note: The actual wrapper function can only be generated 2536 at resolution time. */ 2537 if (!gfc_add_component (vtype, "_final", &c)) 2538 goto cleanup; 2539 c->attr.proc_pointer = 1; 2540 c->attr.access = ACCESS_PRIVATE; 2541 c->attr.artificial = 1; 2542 c->tb = XCNEW (gfc_typebound_proc); 2543 c->tb->ppc = 1; 2544 generate_finalization_wrapper (derived, ns, tname, c); 2545 2546 /* Add component _deallocate. */ 2547 if (!gfc_add_component (vtype, "_deallocate", &c)) 2548 goto cleanup; 2549 c->attr.proc_pointer = 1; 2550 c->attr.access = ACCESS_PRIVATE; 2551 c->tb = XCNEW (gfc_typebound_proc); 2552 c->tb->ppc = 1; 2553 if (derived->attr.unlimited_polymorphic 2554 || derived->attr.abstract 2555 || !rdt) 2556 c->initializer = gfc_get_null_expr (NULL); 2557 else 2558 { 2559 /* Set up namespace. */ 2560 gfc_namespace *sub_ns = gfc_get_namespace (ns, 0); 2561 2562 sub_ns->sibling = ns->contained; 2563 ns->contained = sub_ns; 2564 sub_ns->resolved = 1; 2565 /* Set up procedure symbol. */ 2566 name = xasprintf ("__deallocate_%s", tname); 2567 gfc_get_symbol (name, sub_ns, &dealloc); 2568 sub_ns->proc_name = dealloc; 2569 dealloc->attr.flavor = FL_PROCEDURE; 2570 dealloc->attr.subroutine = 1; 2571 dealloc->attr.pure = 1; 2572 dealloc->attr.artificial = 1; 2573 dealloc->attr.if_source = IFSRC_DECL; 2574 2575 if (ns->proc_name->attr.flavor == FL_MODULE) 2576 dealloc->module = ns->proc_name->name; 2577 gfc_set_sym_referenced (dealloc); 2578 /* Set up formal argument. */ 2579 gfc_get_symbol ("arg", sub_ns, &arg); 2580 arg->ts.type = BT_DERIVED; 2581 arg->ts.u.derived = derived; 2582 arg->attr.flavor = FL_VARIABLE; 2583 arg->attr.dummy = 1; 2584 arg->attr.artificial = 1; 2585 arg->attr.intent = INTENT_INOUT; 2586 arg->attr.dimension = 1; 2587 arg->attr.allocatable = 1; 2588 arg->as = gfc_get_array_spec(); 2589 arg->as->type = AS_ASSUMED_SHAPE; 2590 arg->as->rank = 1; 2591 arg->as->lower[0] = gfc_get_int_expr (gfc_default_integer_kind, 2592 NULL, 1); 2593 gfc_set_sym_referenced (arg); 2594 dealloc->formal = gfc_get_formal_arglist (); 2595 dealloc->formal->sym = arg; 2596 /* Set up code. */ 2597 sub_ns->code = gfc_get_code (EXEC_DEALLOCATE); 2598 sub_ns->code->ext.alloc.list = gfc_get_alloc (); 2599 sub_ns->code->ext.alloc.list->expr 2600 = gfc_lval_expr_from_sym (arg); 2601 /* Set initializer. */ 2602 c->initializer = gfc_lval_expr_from_sym (dealloc); 2603 c->ts.interface = dealloc; 2604 } 2605 2606 /* Add procedure pointers for type-bound procedures. */ 2607 if (!derived->attr.unlimited_polymorphic) 2608 add_procs_to_declared_vtab (derived, vtype); 2609 } 2610 2611 have_vtype: 2612 vtab->ts.u.derived = vtype; 2613 vtab->value = gfc_default_initializer (&vtab->ts); 2614 } 2615 free (name); 2616 } 2617 2618 found_sym = vtab; 2619 2620 cleanup: 2621 /* It is unexpected to have some symbols added at resolution or code 2622 generation time. We commit the changes in order to keep a clean state. */ 2623 if (found_sym) 2624 { 2625 gfc_commit_symbol (vtab); 2626 if (vtype) 2627 gfc_commit_symbol (vtype); 2628 if (def_init) 2629 gfc_commit_symbol (def_init); 2630 if (copy) 2631 gfc_commit_symbol (copy); 2632 if (src) 2633 gfc_commit_symbol (src); 2634 if (dst) 2635 gfc_commit_symbol (dst); 2636 if (dealloc) 2637 gfc_commit_symbol (dealloc); 2638 if (arg) 2639 gfc_commit_symbol (arg); 2640 } 2641 else 2642 gfc_undo_symbols (); 2643 2644 return found_sym; 2645 } 2646 2647 2648 /* Check if a derived type is finalizable. That is the case if it 2649 (1) has a FINAL subroutine or 2650 (2) has a nonpointer nonallocatable component of finalizable type. 2651 If it is finalizable, return an expression containing the 2652 finalization wrapper. */ 2653 2654 bool 2655 gfc_is_finalizable (gfc_symbol *derived, gfc_expr **final_expr) 2656 { 2657 gfc_symbol *vtab; 2658 gfc_component *c; 2659 2660 /* (1) Check for FINAL subroutines. */ 2661 if (derived->f2k_derived && derived->f2k_derived->finalizers) 2662 goto yes; 2663 2664 /* (2) Check for components of finalizable type. */ 2665 for (c = derived->components; c; c = c->next) 2666 if (c->ts.type == BT_DERIVED 2667 && !c->attr.pointer && !c->attr.proc_pointer && !c->attr.allocatable 2668 && gfc_is_finalizable (c->ts.u.derived, NULL)) 2669 goto yes; 2670 2671 return false; 2672 2673 yes: 2674 /* Make sure vtab is generated. */ 2675 vtab = gfc_find_derived_vtab (derived); 2676 if (final_expr) 2677 { 2678 /* Return finalizer expression. */ 2679 gfc_component *final; 2680 final = vtab->ts.u.derived->components->next->next->next->next->next; 2681 gcc_assert (strcmp (final->name, "_final") == 0); 2682 gcc_assert (final->initializer 2683 && final->initializer->expr_type != EXPR_NULL); 2684 *final_expr = final->initializer; 2685 } 2686 return true; 2687 } 2688 2689 2690 /* Find (or generate) the symbol for an intrinsic type's vtab. This is 2691 needed to support unlimited polymorphism. */ 2692 2693 static gfc_symbol * 2694 find_intrinsic_vtab (gfc_typespec *ts) 2695 { 2696 gfc_namespace *ns; 2697 gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL; 2698 gfc_symbol *copy = NULL, *src = NULL, *dst = NULL; 2699 2700 /* Find the top-level namespace. */ 2701 for (ns = gfc_current_ns; ns; ns = ns->parent) 2702 if (!ns->parent) 2703 break; 2704 2705 if (ns) 2706 { 2707 char tname[GFC_MAX_SYMBOL_LEN+1]; 2708 char *name; 2709 2710 /* Encode all types as TYPENAME_KIND_ including especially character 2711 arrays, whose length is now consistently stored in the _len component 2712 of the class-variable. */ 2713 sprintf (tname, "%s_%d_", gfc_basic_typename (ts->type), ts->kind); 2714 name = xasprintf ("__vtab_%s", tname); 2715 2716 /* Look for the vtab symbol in the top-level namespace only. */ 2717 gfc_find_symbol (name, ns, 0, &vtab); 2718 2719 if (vtab == NULL) 2720 { 2721 gfc_get_symbol (name, ns, &vtab); 2722 vtab->ts.type = BT_DERIVED; 2723 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL, 2724 &gfc_current_locus)) 2725 goto cleanup; 2726 vtab->attr.target = 1; 2727 vtab->attr.save = SAVE_IMPLICIT; 2728 vtab->attr.vtab = 1; 2729 vtab->attr.access = ACCESS_PUBLIC; 2730 gfc_set_sym_referenced (vtab); 2731 name = xasprintf ("__vtype_%s", tname); 2732 2733 gfc_find_symbol (name, ns, 0, &vtype); 2734 if (vtype == NULL) 2735 { 2736 gfc_component *c; 2737 int hash; 2738 gfc_namespace *sub_ns; 2739 gfc_namespace *contained; 2740 gfc_expr *e; 2741 size_t e_size; 2742 2743 gfc_get_symbol (name, ns, &vtype); 2744 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL, 2745 &gfc_current_locus)) 2746 goto cleanup; 2747 vtype->attr.access = ACCESS_PUBLIC; 2748 vtype->attr.vtype = 1; 2749 gfc_set_sym_referenced (vtype); 2750 2751 /* Add component '_hash'. */ 2752 if (!gfc_add_component (vtype, "_hash", &c)) 2753 goto cleanup; 2754 c->ts.type = BT_INTEGER; 2755 c->ts.kind = 4; 2756 c->attr.access = ACCESS_PRIVATE; 2757 hash = gfc_intrinsic_hash_value (ts); 2758 c->initializer = gfc_get_int_expr (gfc_default_integer_kind, 2759 NULL, hash); 2760 2761 /* Add component '_size'. */ 2762 if (!gfc_add_component (vtype, "_size", &c)) 2763 goto cleanup; 2764 c->ts.type = BT_INTEGER; 2765 c->ts.kind = gfc_size_kind; 2766 c->attr.access = ACCESS_PRIVATE; 2767 2768 /* Build a minimal expression to make use of 2769 target-memory.c/gfc_element_size for 'size'. Special handling 2770 for character arrays, that are not constant sized: to support 2771 len (str) * kind, only the kind information is stored in the 2772 vtab. */ 2773 e = gfc_get_expr (); 2774 e->ts = *ts; 2775 e->expr_type = EXPR_VARIABLE; 2776 if (ts->type == BT_CHARACTER) 2777 e_size = ts->kind; 2778 else 2779 gfc_element_size (e, &e_size); 2780 c->initializer = gfc_get_int_expr (gfc_size_kind, 2781 NULL, 2782 e_size); 2783 gfc_free_expr (e); 2784 2785 /* Add component _extends. */ 2786 if (!gfc_add_component (vtype, "_extends", &c)) 2787 goto cleanup; 2788 c->attr.pointer = 1; 2789 c->attr.access = ACCESS_PRIVATE; 2790 c->ts.type = BT_VOID; 2791 c->initializer = gfc_get_null_expr (NULL); 2792 2793 /* Add component _def_init. */ 2794 if (!gfc_add_component (vtype, "_def_init", &c)) 2795 goto cleanup; 2796 c->attr.pointer = 1; 2797 c->attr.access = ACCESS_PRIVATE; 2798 c->ts.type = BT_VOID; 2799 c->initializer = gfc_get_null_expr (NULL); 2800 2801 /* Add component _copy. */ 2802 if (!gfc_add_component (vtype, "_copy", &c)) 2803 goto cleanup; 2804 c->attr.proc_pointer = 1; 2805 c->attr.access = ACCESS_PRIVATE; 2806 c->tb = XCNEW (gfc_typebound_proc); 2807 c->tb->ppc = 1; 2808 2809 if (ts->type != BT_CHARACTER) 2810 name = xasprintf ("__copy_%s", tname); 2811 else 2812 { 2813 /* __copy is always the same for characters. 2814 Check to see if copy function already exists. */ 2815 name = xasprintf ("__copy_character_%d", ts->kind); 2816 contained = ns->contained; 2817 for (; contained; contained = contained->sibling) 2818 if (contained->proc_name 2819 && strcmp (name, contained->proc_name->name) == 0) 2820 { 2821 copy = contained->proc_name; 2822 goto got_char_copy; 2823 } 2824 } 2825 2826 /* Set up namespace. */ 2827 sub_ns = gfc_get_namespace (ns, 0); 2828 sub_ns->sibling = ns->contained; 2829 ns->contained = sub_ns; 2830 sub_ns->resolved = 1; 2831 /* Set up procedure symbol. */ 2832 gfc_get_symbol (name, sub_ns, ©); 2833 sub_ns->proc_name = copy; 2834 copy->attr.flavor = FL_PROCEDURE; 2835 copy->attr.subroutine = 1; 2836 copy->attr.pure = 1; 2837 copy->attr.if_source = IFSRC_DECL; 2838 /* This is elemental so that arrays are automatically 2839 treated correctly by the scalarizer. */ 2840 copy->attr.elemental = 1; 2841 if (ns->proc_name && ns->proc_name->attr.flavor == FL_MODULE) 2842 copy->module = ns->proc_name->name; 2843 gfc_set_sym_referenced (copy); 2844 /* Set up formal arguments. */ 2845 gfc_get_symbol ("src", sub_ns, &src); 2846 src->ts.type = ts->type; 2847 src->ts.kind = ts->kind; 2848 src->attr.flavor = FL_VARIABLE; 2849 src->attr.dummy = 1; 2850 src->attr.intent = INTENT_IN; 2851 gfc_set_sym_referenced (src); 2852 copy->formal = gfc_get_formal_arglist (); 2853 copy->formal->sym = src; 2854 gfc_get_symbol ("dst", sub_ns, &dst); 2855 dst->ts.type = ts->type; 2856 dst->ts.kind = ts->kind; 2857 dst->attr.flavor = FL_VARIABLE; 2858 dst->attr.dummy = 1; 2859 dst->attr.intent = INTENT_INOUT; 2860 gfc_set_sym_referenced (dst); 2861 copy->formal->next = gfc_get_formal_arglist (); 2862 copy->formal->next->sym = dst; 2863 /* Set up code. */ 2864 sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN); 2865 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst); 2866 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src); 2867 got_char_copy: 2868 /* Set initializer. */ 2869 c->initializer = gfc_lval_expr_from_sym (copy); 2870 c->ts.interface = copy; 2871 2872 /* Add component _final. */ 2873 if (!gfc_add_component (vtype, "_final", &c)) 2874 goto cleanup; 2875 c->attr.proc_pointer = 1; 2876 c->attr.access = ACCESS_PRIVATE; 2877 c->attr.artificial = 1; 2878 c->tb = XCNEW (gfc_typebound_proc); 2879 c->tb->ppc = 1; 2880 c->initializer = gfc_get_null_expr (NULL); 2881 } 2882 vtab->ts.u.derived = vtype; 2883 vtab->value = gfc_default_initializer (&vtab->ts); 2884 } 2885 free (name); 2886 } 2887 2888 found_sym = vtab; 2889 2890 cleanup: 2891 /* It is unexpected to have some symbols added at resolution or code 2892 generation time. We commit the changes in order to keep a clean state. */ 2893 if (found_sym) 2894 { 2895 gfc_commit_symbol (vtab); 2896 if (vtype) 2897 gfc_commit_symbol (vtype); 2898 if (copy) 2899 gfc_commit_symbol (copy); 2900 if (src) 2901 gfc_commit_symbol (src); 2902 if (dst) 2903 gfc_commit_symbol (dst); 2904 } 2905 else 2906 gfc_undo_symbols (); 2907 2908 return found_sym; 2909 } 2910 2911 2912 /* Find (or generate) a vtab for an arbitrary type (derived or intrinsic). */ 2913 2914 gfc_symbol * 2915 gfc_find_vtab (gfc_typespec *ts) 2916 { 2917 switch (ts->type) 2918 { 2919 case BT_UNKNOWN: 2920 return NULL; 2921 case BT_DERIVED: 2922 return gfc_find_derived_vtab (ts->u.derived); 2923 case BT_CLASS: 2924 if (ts->u.derived->attr.is_class 2925 && ts->u.derived->components 2926 && ts->u.derived->components->ts.u.derived) 2927 return gfc_find_derived_vtab (ts->u.derived->components->ts.u.derived); 2928 else 2929 return NULL; 2930 default: 2931 return find_intrinsic_vtab (ts); 2932 } 2933 } 2934 2935 2936 /* General worker function to find either a type-bound procedure or a 2937 type-bound user operator. */ 2938 2939 static gfc_symtree* 2940 find_typebound_proc_uop (gfc_symbol* derived, bool* t, 2941 const char* name, bool noaccess, bool uop, 2942 locus* where) 2943 { 2944 gfc_symtree* res; 2945 gfc_symtree* root; 2946 2947 /* Set default to failure. */ 2948 if (t) 2949 *t = false; 2950 2951 if (derived->f2k_derived) 2952 /* Set correct symbol-root. */ 2953 root = (uop ? derived->f2k_derived->tb_uop_root 2954 : derived->f2k_derived->tb_sym_root); 2955 else 2956 return NULL; 2957 2958 /* Try to find it in the current type's namespace. */ 2959 res = gfc_find_symtree (root, name); 2960 if (res && res->n.tb && !res->n.tb->error) 2961 { 2962 /* We found one. */ 2963 if (t) 2964 *t = true; 2965 2966 if (!noaccess && derived->attr.use_assoc 2967 && res->n.tb->access == ACCESS_PRIVATE) 2968 { 2969 if (where) 2970 gfc_error ("%qs of %qs is PRIVATE at %L", 2971 name, derived->name, where); 2972 if (t) 2973 *t = false; 2974 } 2975 2976 return res; 2977 } 2978 2979 /* Otherwise, recurse on parent type if derived is an extension. */ 2980 if (derived->attr.extension) 2981 { 2982 gfc_symbol* super_type; 2983 super_type = gfc_get_derived_super_type (derived); 2984 gcc_assert (super_type); 2985 2986 return find_typebound_proc_uop (super_type, t, name, 2987 noaccess, uop, where); 2988 } 2989 2990 /* Nothing found. */ 2991 return NULL; 2992 } 2993 2994 2995 /* Find a type-bound procedure or user operator by name for a derived-type 2996 (looking recursively through the super-types). */ 2997 2998 gfc_symtree* 2999 gfc_find_typebound_proc (gfc_symbol* derived, bool* t, 3000 const char* name, bool noaccess, locus* where) 3001 { 3002 return find_typebound_proc_uop (derived, t, name, noaccess, false, where); 3003 } 3004 3005 gfc_symtree* 3006 gfc_find_typebound_user_op (gfc_symbol* derived, bool* t, 3007 const char* name, bool noaccess, locus* where) 3008 { 3009 return find_typebound_proc_uop (derived, t, name, noaccess, true, where); 3010 } 3011 3012 3013 /* Find a type-bound intrinsic operator looking recursively through the 3014 super-type hierarchy. */ 3015 3016 gfc_typebound_proc* 3017 gfc_find_typebound_intrinsic_op (gfc_symbol* derived, bool* t, 3018 gfc_intrinsic_op op, bool noaccess, 3019 locus* where) 3020 { 3021 gfc_typebound_proc* res; 3022 3023 /* Set default to failure. */ 3024 if (t) 3025 *t = false; 3026 3027 /* Try to find it in the current type's namespace. */ 3028 if (derived->f2k_derived) 3029 res = derived->f2k_derived->tb_op[op]; 3030 else 3031 res = NULL; 3032 3033 /* Check access. */ 3034 if (res && !res->error) 3035 { 3036 /* We found one. */ 3037 if (t) 3038 *t = true; 3039 3040 if (!noaccess && derived->attr.use_assoc 3041 && res->access == ACCESS_PRIVATE) 3042 { 3043 if (where) 3044 gfc_error ("%qs of %qs is PRIVATE at %L", 3045 gfc_op2string (op), derived->name, where); 3046 if (t) 3047 *t = false; 3048 } 3049 3050 return res; 3051 } 3052 3053 /* Otherwise, recurse on parent type if derived is an extension. */ 3054 if (derived->attr.extension) 3055 { 3056 gfc_symbol* super_type; 3057 super_type = gfc_get_derived_super_type (derived); 3058 gcc_assert (super_type); 3059 3060 return gfc_find_typebound_intrinsic_op (super_type, t, op, 3061 noaccess, where); 3062 } 3063 3064 /* Nothing found. */ 3065 return NULL; 3066 } 3067 3068 3069 /* Get a typebound-procedure symtree or create and insert it if not yet 3070 present. This is like a very simplified version of gfc_get_sym_tree for 3071 tbp-symtrees rather than regular ones. */ 3072 3073 gfc_symtree* 3074 gfc_get_tbp_symtree (gfc_symtree **root, const char *name) 3075 { 3076 gfc_symtree *result = gfc_find_symtree (*root, name); 3077 return result ? result : gfc_new_symtree (root, name); 3078 } 3079