comparison gcc/fortran/class.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
1 /* Implementation of Fortran 2003 Polymorphism. 1 /* Implementation of Fortran 2003 Polymorphism.
2 Copyright (C) 2009-2017 Free Software Foundation, Inc. 2 Copyright (C) 2009-2018 Free Software Foundation, Inc.
3 Contributed by Paul Richard Thomas <pault@gcc.gnu.org> 3 Contributed by Paul Richard Thomas <pault@gcc.gnu.org>
4 and Janus Weil <janus@gcc.gnu.org> 4 and Janus Weil <janus@gcc.gnu.org>
5 5
6 This file is part of GCC. 6 This file is part of GCC.
7 7
33 declared type of the class variable and its attributes 33 declared type of the class variable and its attributes
34 (pointer/allocatable/dimension/...). 34 (pointer/allocatable/dimension/...).
35 * _vptr: A pointer to the vtable entry (see below) of the dynamic type. 35 * _vptr: A pointer to the vtable entry (see below) of the dynamic type.
36 36
37 Only for unlimited polymorphic classes: 37 Only for unlimited polymorphic classes:
38 * _len: An integer(4) to store the string length when the unlimited 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' 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 40 component will be zero when no character array is stored in
41 '_data'. 41 '_data'.
42 42
43 For each derived type we set up a "vtable" entry, i.e. a structure with the 43 For each derived type we set up a "vtable" entry, i.e. a structure with the
306 with_data = true; 306 with_data = true;
307 if (full_array) 307 if (full_array)
308 *full_array = true; 308 *full_array = true;
309 } 309 }
310 else if (ref->next && ref->next->type == REF_ARRAY 310 else if (ref->next && ref->next->type == REF_ARRAY
311 && !ref->next->next
312 && ref->type == REF_COMPONENT 311 && ref->type == REF_COMPONENT
313 && ref->next->u.ar.type != AR_ELEMENT) 312 && ref->next->u.ar.type != AR_ELEMENT)
314 { 313 {
315 with_data = true; 314 with_data = true;
316 if (full_array) 315 if (full_array)
600 599
601 bool 600 bool
602 gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr, 601 gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
603 gfc_array_spec **as) 602 gfc_array_spec **as)
604 { 603 {
605 char name[GFC_MAX_SYMBOL_LEN+1], tname[GFC_MAX_SYMBOL_LEN+1]; 604 char tname[GFC_MAX_SYMBOL_LEN+1];
605 char *name;
606 gfc_symbol *fclass; 606 gfc_symbol *fclass;
607 gfc_symbol *vtab; 607 gfc_symbol *vtab;
608 gfc_component *c; 608 gfc_component *c;
609 gfc_namespace *ns; 609 gfc_namespace *ns;
610 int rank; 610 int rank;
631 631
632 /* Determine the name of the encapsulating type. */ 632 /* Determine the name of the encapsulating type. */
633 rank = !(*as) || (*as)->rank == -1 ? GFC_MAX_DIMENSIONS : (*as)->rank; 633 rank = !(*as) || (*as)->rank == -1 ? GFC_MAX_DIMENSIONS : (*as)->rank;
634 get_unique_hashed_string (tname, ts->u.derived); 634 get_unique_hashed_string (tname, ts->u.derived);
635 if ((*as) && attr->allocatable) 635 if ((*as) && attr->allocatable)
636 sprintf (name, "__class_%s_%d_%da", tname, rank, (*as)->corank); 636 name = xasprintf ("__class_%s_%d_%da", tname, rank, (*as)->corank);
637 else if ((*as) && attr->pointer) 637 else if ((*as) && attr->pointer)
638 sprintf (name, "__class_%s_%d_%dp", tname, rank, (*as)->corank); 638 name = xasprintf ("__class_%s_%d_%dp", tname, rank, (*as)->corank);
639 else if ((*as)) 639 else if ((*as))
640 sprintf (name, "__class_%s_%d_%dt", tname, rank, (*as)->corank); 640 name = xasprintf ("__class_%s_%d_%dt", tname, rank, (*as)->corank);
641 else if (attr->pointer) 641 else if (attr->pointer)
642 sprintf (name, "__class_%s_p", tname); 642 name = xasprintf ("__class_%s_p", tname);
643 else if (attr->allocatable) 643 else if (attr->allocatable)
644 sprintf (name, "__class_%s_a", tname); 644 name = xasprintf ("__class_%s_a", tname);
645 else 645 else
646 sprintf (name, "__class_%s_t", tname); 646 name = xasprintf ("__class_%s_t", tname);
647 647
648 if (ts->u.derived->attr.unlimited_polymorphic) 648 if (ts->u.derived->attr.unlimited_polymorphic)
649 { 649 {
650 /* Find the top-level namespace. */ 650 /* Find the top-level namespace. */
651 for (ns = gfc_current_ns; ns; ns = ns->parent) 651 for (ns = gfc_current_ns; ns; ns = ns->parent)
736 736
737 fclass->attr.is_class = 1; 737 fclass->attr.is_class = 1;
738 ts->u.derived = fclass; 738 ts->u.derived = fclass;
739 attr->allocatable = attr->pointer = attr->dimension = attr->codimension = 0; 739 attr->allocatable = attr->pointer = attr->dimension = attr->codimension = 0;
740 (*as) = NULL; 740 (*as) = NULL;
741 free (name);
741 return true; 742 return true;
742 } 743 }
743 744
744 745
745 /* Add a procedure pointer component to the vtype 746 /* Add a procedure pointer component to the vtype
1525 gfc_symbol *final, *array, *fini_coarray, *byte_stride, *sizes, *strides; 1526 gfc_symbol *final, *array, *fini_coarray, *byte_stride, *sizes, *strides;
1526 gfc_symbol *ptr = NULL, *idx, *idx2, *is_contiguous, *offset, *nelem; 1527 gfc_symbol *ptr = NULL, *idx, *idx2, *is_contiguous, *offset, *nelem;
1527 gfc_component *comp; 1528 gfc_component *comp;
1528 gfc_namespace *sub_ns; 1529 gfc_namespace *sub_ns;
1529 gfc_code *last_code, *block; 1530 gfc_code *last_code, *block;
1530 char name[GFC_MAX_SYMBOL_LEN+1]; 1531 char *name;
1531 bool finalizable_comp = false; 1532 bool finalizable_comp = false;
1532 bool expr_null_wrapper = false; 1533 bool expr_null_wrapper = false;
1533 gfc_expr *ancestor_wrapper = NULL, *rank; 1534 gfc_expr *ancestor_wrapper = NULL, *rank;
1534 gfc_iterator *iter; 1535 gfc_iterator *iter;
1535 1536
1604 if (!expr_null_wrapper) 1605 if (!expr_null_wrapper)
1605 ns->contained = sub_ns; 1606 ns->contained = sub_ns;
1606 sub_ns->resolved = 1; 1607 sub_ns->resolved = 1;
1607 1608
1608 /* Set up the procedure symbol. */ 1609 /* Set up the procedure symbol. */
1609 sprintf (name, "__final_%s", tname); 1610 name = xasprintf ("__final_%s", tname);
1610 gfc_get_symbol (name, sub_ns, &final); 1611 gfc_get_symbol (name, sub_ns, &final);
1611 sub_ns->proc_name = final; 1612 sub_ns->proc_name = final;
1612 final->attr.flavor = FL_PROCEDURE; 1613 final->attr.flavor = FL_PROCEDURE;
1613 final->attr.function = 1; 1614 final->attr.function = 1;
1614 final->attr.pure = 0; 1615 final->attr.pure = 0;
2170 } 2171 }
2171 2172
2172 gfc_free_expr (rank); 2173 gfc_free_expr (rank);
2173 vtab_final->initializer = gfc_lval_expr_from_sym (final); 2174 vtab_final->initializer = gfc_lval_expr_from_sym (final);
2174 vtab_final->ts.interface = final; 2175 vtab_final->ts.interface = final;
2176 free (name);
2175 } 2177 }
2176 2178
2177 2179
2178 /* Add procedure pointers for all type-bound procedures to a vtab. */ 2180 /* Add procedure pointers for all type-bound procedures to a vtab. */
2179 2181
2237 && ns->proc_name->attr.flavor == FL_MODULE) 2239 && ns->proc_name->attr.flavor == FL_MODULE)
2238 ns = gsym->ns; 2240 ns = gsym->ns;
2239 2241
2240 if (ns) 2242 if (ns)
2241 { 2243 {
2242 char name[GFC_MAX_SYMBOL_LEN+1], tname[GFC_MAX_SYMBOL_LEN+1]; 2244 char tname[GFC_MAX_SYMBOL_LEN+1];
2245 char *name;
2243 2246
2244 get_unique_hashed_string (tname, derived); 2247 get_unique_hashed_string (tname, derived);
2245 sprintf (name, "__vtab_%s", tname); 2248 name = xasprintf ("__vtab_%s", tname);
2246 2249
2247 /* Look for the vtab symbol in various namespaces. */ 2250 /* Look for the vtab symbol in various namespaces. */
2248 if (gsym && gsym->ns) 2251 if (gsym && gsym->ns)
2249 { 2252 {
2250 gfc_find_symbol (name, gsym->ns, 0, &vtab); 2253 gfc_find_symbol (name, gsym->ns, 0, &vtab);
2268 vtab->attr.target = 1; 2271 vtab->attr.target = 1;
2269 vtab->attr.save = SAVE_IMPLICIT; 2272 vtab->attr.save = SAVE_IMPLICIT;
2270 vtab->attr.vtab = 1; 2273 vtab->attr.vtab = 1;
2271 vtab->attr.access = ACCESS_PUBLIC; 2274 vtab->attr.access = ACCESS_PUBLIC;
2272 gfc_set_sym_referenced (vtab); 2275 gfc_set_sym_referenced (vtab);
2273 sprintf (name, "__vtype_%s", tname); 2276 name = xasprintf ("__vtype_%s", tname);
2274 2277
2275 gfc_find_symbol (name, ns, 0, &vtype); 2278 gfc_find_symbol (name, ns, 0, &vtype);
2276 if (vtype == NULL) 2279 if (vtype == NULL)
2277 { 2280 {
2278 gfc_component *c; 2281 gfc_component *c;
2311 2314
2312 /* Add component '_size'. */ 2315 /* Add component '_size'. */
2313 if (!gfc_add_component (vtype, "_size", &c)) 2316 if (!gfc_add_component (vtype, "_size", &c))
2314 goto cleanup; 2317 goto cleanup;
2315 c->ts.type = BT_INTEGER; 2318 c->ts.type = BT_INTEGER;
2316 c->ts.kind = 4; 2319 c->ts.kind = gfc_size_kind;
2317 c->attr.access = ACCESS_PRIVATE; 2320 c->attr.access = ACCESS_PRIVATE;
2318 /* Remember the derived type in ts.u.derived, 2321 /* Remember the derived type in ts.u.derived,
2319 so that the correct initializer can be set later on 2322 so that the correct initializer can be set later on
2320 (in gfc_conv_structure). */ 2323 (in gfc_conv_structure). */
2321 c->ts.u.derived = derived; 2324 c->ts.u.derived = derived;
2322 c->initializer = gfc_get_int_expr (gfc_default_integer_kind, 2325 c->initializer = gfc_get_int_expr (gfc_size_kind,
2323 NULL, 0); 2326 NULL, 0);
2324 2327
2325 /* Add component _extends. */ 2328 /* Add component _extends. */
2326 if (!gfc_add_component (vtype, "_extends", &c)) 2329 if (!gfc_add_component (vtype, "_extends", &c))
2327 goto cleanup; 2330 goto cleanup;
2371 || derived->attr.abstract) 2374 || derived->attr.abstract)
2372 c->initializer = gfc_get_null_expr (NULL); 2375 c->initializer = gfc_get_null_expr (NULL);
2373 else 2376 else
2374 { 2377 {
2375 /* Construct default initialization variable. */ 2378 /* Construct default initialization variable. */
2376 sprintf (name, "__def_init_%s", tname); 2379 name = xasprintf ("__def_init_%s", tname);
2377 gfc_get_symbol (name, ns, &def_init); 2380 gfc_get_symbol (name, ns, &def_init);
2378 def_init->attr.target = 1; 2381 def_init->attr.target = 1;
2379 def_init->attr.artificial = 1; 2382 def_init->attr.artificial = 1;
2380 def_init->attr.save = SAVE_IMPLICIT; 2383 def_init->attr.save = SAVE_IMPLICIT;
2381 def_init->attr.access = ACCESS_PUBLIC; 2384 def_init->attr.access = ACCESS_PUBLIC;
2404 gfc_namespace *sub_ns = gfc_get_namespace (ns, 0); 2407 gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
2405 sub_ns->sibling = ns->contained; 2408 sub_ns->sibling = ns->contained;
2406 ns->contained = sub_ns; 2409 ns->contained = sub_ns;
2407 sub_ns->resolved = 1; 2410 sub_ns->resolved = 1;
2408 /* Set up procedure symbol. */ 2411 /* Set up procedure symbol. */
2409 sprintf (name, "__copy_%s", tname); 2412 name = xasprintf ("__copy_%s", tname);
2410 gfc_get_symbol (name, sub_ns, &copy); 2413 gfc_get_symbol (name, sub_ns, &copy);
2411 sub_ns->proc_name = copy; 2414 sub_ns->proc_name = copy;
2412 copy->attr.flavor = FL_PROCEDURE; 2415 copy->attr.flavor = FL_PROCEDURE;
2413 copy->attr.subroutine = 1; 2416 copy->attr.subroutine = 1;
2414 copy->attr.pure = 1; 2417 copy->attr.pure = 1;
2481 2484
2482 sub_ns->sibling = ns->contained; 2485 sub_ns->sibling = ns->contained;
2483 ns->contained = sub_ns; 2486 ns->contained = sub_ns;
2484 sub_ns->resolved = 1; 2487 sub_ns->resolved = 1;
2485 /* Set up procedure symbol. */ 2488 /* Set up procedure symbol. */
2486 sprintf (name, "__deallocate_%s", tname); 2489 name = xasprintf ("__deallocate_%s", tname);
2487 gfc_get_symbol (name, sub_ns, &dealloc); 2490 gfc_get_symbol (name, sub_ns, &dealloc);
2488 sub_ns->proc_name = dealloc; 2491 sub_ns->proc_name = dealloc;
2489 dealloc->attr.flavor = FL_PROCEDURE; 2492 dealloc->attr.flavor = FL_PROCEDURE;
2490 dealloc->attr.subroutine = 1; 2493 dealloc->attr.subroutine = 1;
2491 dealloc->attr.pure = 1; 2494 dealloc->attr.pure = 1;
2530 2533
2531 have_vtype: 2534 have_vtype:
2532 vtab->ts.u.derived = vtype; 2535 vtab->ts.u.derived = vtype;
2533 vtab->value = gfc_default_initializer (&vtab->ts); 2536 vtab->value = gfc_default_initializer (&vtab->ts);
2534 } 2537 }
2538 free (name);
2535 } 2539 }
2536 2540
2537 found_sym = vtab; 2541 found_sym = vtab;
2538 2542
2539 cleanup: 2543 cleanup:
2621 if (!ns->parent) 2625 if (!ns->parent)
2622 break; 2626 break;
2623 2627
2624 if (ns) 2628 if (ns)
2625 { 2629 {
2626 char name[GFC_MAX_SYMBOL_LEN+1], tname[GFC_MAX_SYMBOL_LEN+1]; 2630 char tname[GFC_MAX_SYMBOL_LEN+1];
2631 char *name;
2627 2632
2628 /* Encode all types as TYPENAME_KIND_ including especially character 2633 /* Encode all types as TYPENAME_KIND_ including especially character
2629 arrays, whose length is now consistently stored in the _len component 2634 arrays, whose length is now consistently stored in the _len component
2630 of the class-variable. */ 2635 of the class-variable. */
2631 sprintf (tname, "%s_%d_", gfc_basic_typename (ts->type), ts->kind); 2636 sprintf (tname, "%s_%d_", gfc_basic_typename (ts->type), ts->kind);
2632 sprintf (name, "__vtab_%s", tname); 2637 name = xasprintf ("__vtab_%s", tname);
2633 2638
2634 /* Look for the vtab symbol in the top-level namespace only. */ 2639 /* Look for the vtab symbol in the top-level namespace only. */
2635 gfc_find_symbol (name, ns, 0, &vtab); 2640 gfc_find_symbol (name, ns, 0, &vtab);
2636 2641
2637 if (vtab == NULL) 2642 if (vtab == NULL)
2644 vtab->attr.target = 1; 2649 vtab->attr.target = 1;
2645 vtab->attr.save = SAVE_IMPLICIT; 2650 vtab->attr.save = SAVE_IMPLICIT;
2646 vtab->attr.vtab = 1; 2651 vtab->attr.vtab = 1;
2647 vtab->attr.access = ACCESS_PUBLIC; 2652 vtab->attr.access = ACCESS_PUBLIC;
2648 gfc_set_sym_referenced (vtab); 2653 gfc_set_sym_referenced (vtab);
2649 sprintf (name, "__vtype_%s", tname); 2654 name = xasprintf ("__vtype_%s", tname);
2650 2655
2651 gfc_find_symbol (name, ns, 0, &vtype); 2656 gfc_find_symbol (name, ns, 0, &vtype);
2652 if (vtype == NULL) 2657 if (vtype == NULL)
2653 { 2658 {
2654 gfc_component *c; 2659 gfc_component *c;
2677 2682
2678 /* Add component '_size'. */ 2683 /* Add component '_size'. */
2679 if (!gfc_add_component (vtype, "_size", &c)) 2684 if (!gfc_add_component (vtype, "_size", &c))
2680 goto cleanup; 2685 goto cleanup;
2681 c->ts.type = BT_INTEGER; 2686 c->ts.type = BT_INTEGER;
2682 c->ts.kind = 4; 2687 c->ts.kind = gfc_size_kind;
2683 c->attr.access = ACCESS_PRIVATE; 2688 c->attr.access = ACCESS_PRIVATE;
2684 2689
2685 /* Build a minimal expression to make use of 2690 /* Build a minimal expression to make use of
2686 target-memory.c/gfc_element_size for 'size'. Special handling 2691 target-memory.c/gfc_element_size for 'size'. Special handling
2687 for character arrays, that are not constant sized: to support 2692 for character arrays, that are not constant sized: to support
2688 len (str) * kind, only the kind information is stored in the 2693 len (str) * kind, only the kind information is stored in the
2689 vtab. */ 2694 vtab. */
2690 e = gfc_get_expr (); 2695 e = gfc_get_expr ();
2691 e->ts = *ts; 2696 e->ts = *ts;
2692 e->expr_type = EXPR_VARIABLE; 2697 e->expr_type = EXPR_VARIABLE;
2693 c->initializer = gfc_get_int_expr (gfc_default_integer_kind, 2698 c->initializer = gfc_get_int_expr (gfc_size_kind,
2694 NULL, 2699 NULL,
2695 ts->type == BT_CHARACTER 2700 ts->type == BT_CHARACTER
2696 ? ts->kind 2701 ? ts->kind
2697 : (int)gfc_element_size (e)); 2702 : gfc_element_size (e));
2698 gfc_free_expr (e); 2703 gfc_free_expr (e);
2699 2704
2700 /* Add component _extends. */ 2705 /* Add component _extends. */
2701 if (!gfc_add_component (vtype, "_extends", &c)) 2706 if (!gfc_add_component (vtype, "_extends", &c))
2702 goto cleanup; 2707 goto cleanup;
2720 c->attr.access = ACCESS_PRIVATE; 2725 c->attr.access = ACCESS_PRIVATE;
2721 c->tb = XCNEW (gfc_typebound_proc); 2726 c->tb = XCNEW (gfc_typebound_proc);
2722 c->tb->ppc = 1; 2727 c->tb->ppc = 1;
2723 2728
2724 if (ts->type != BT_CHARACTER) 2729 if (ts->type != BT_CHARACTER)
2725 sprintf (name, "__copy_%s", tname); 2730 name = xasprintf ("__copy_%s", tname);
2726 else 2731 else
2727 { 2732 {
2728 /* __copy is always the same for characters. 2733 /* __copy is always the same for characters.
2729 Check to see if copy function already exists. */ 2734 Check to see if copy function already exists. */
2730 sprintf (name, "__copy_character_%d", ts->kind); 2735 name = xasprintf ("__copy_character_%d", ts->kind);
2731 contained = ns->contained; 2736 contained = ns->contained;
2732 for (; contained; contained = contained->sibling) 2737 for (; contained; contained = contained->sibling)
2733 if (contained->proc_name 2738 if (contained->proc_name
2734 && strcmp (name, contained->proc_name->name) == 0) 2739 && strcmp (name, contained->proc_name->name) == 0)
2735 { 2740 {
2794 c->initializer = gfc_get_null_expr (NULL); 2799 c->initializer = gfc_get_null_expr (NULL);
2795 } 2800 }
2796 vtab->ts.u.derived = vtype; 2801 vtab->ts.u.derived = vtype;
2797 vtab->value = gfc_default_initializer (&vtab->ts); 2802 vtab->value = gfc_default_initializer (&vtab->ts);
2798 } 2803 }
2804 free (name);
2799 } 2805 }
2800 2806
2801 found_sym = vtab; 2807 found_sym = vtab;
2802 2808
2803 cleanup: 2809 cleanup: