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