Skip to content

Commit 0918a2f

Browse files
committed
Implement fixed- and deferred-length character in array constructor
It works with the following 14 cases for both fixed-length and deferred-length character arrays: 1) b = a 2) b = [ a(1), a(2), a(3), a(4) ] 3) b = [ a ] 4) b = [ character(len=newlen) :: a, c ] 5) b = [ character(len=newlen) :: c, a ] 6) b = [ (a(n), n=1,size(a)) ] 7) b = [ character(len=len(a)) :: (a(n), n=1,size(a)) ] 8) b = [ character(len=newlen) :: (a(n), n=1,size(a)), c ] 9) b = [ character(len=len(a)) :: a ] 10) b = [ a(1:2) ] 11) b = [ character(len=len(a)) :: a(:) ] 12) b = [ character(len=newlen) :: a(:), c ] 13) b = [ character(len=newlen) :: c, a(:) ] 14) b = [ character(len=newlen) :: a(1:2), c, a(3:) ] For fixed-length character arrays: character(len=8), allocatable :: a(:) character(len=8), allocatable :: b(:) character(len=8), allocatable :: c a = [ character(len=8) :: "1","2","3","4" ] c = "w" For deferred-length character arrays: character(len=:), allocatable :: a(:) character(len=:), allocatable :: b(:) character(len=:), allocatable :: c a = [ character(len=8) :: "1","2","3","4" ] c = "w"
1 parent 1dce76d commit 0918a2f

File tree

5 files changed

+180
-43
lines changed

5 files changed

+180
-43
lines changed

tools/flang1/flang1exe/dtypeutl.c

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,13 @@ size_ast(int sptr, DTYPE dtype)
573573
if (dtype == DT_ASSCHAR || dtype == DT_DEFERCHAR
574574
|| dtype == DT_ASSNCHAR || dtype == DT_DEFERNCHAR
575575
) {
576-
clen = ast_intr(I_LEN, astb.bnd.dtype, 1, mk_id(sptr));
576+
if (dtype == DT_ASSCHAR || dtype == DT_DEFERCHAR
577+
|| dtype == DT_ASSNCHAR || dtype == DT_DEFERNCHAR
578+
) {
579+
clen = ast_intr(I_LEN, astb.bnd.dtype, 1, mk_id(sptr));
580+
} else {
581+
clen = DTY(dtype+1);
582+
}
577583
} else if (ADJLENG(sptr) && !F90POINTERG(sptr)) {
578584
/* don't add CVLEN for local automatic character */
579585
clen = CVLENG(sptr);
@@ -2387,6 +2393,86 @@ getast(int ast, char *string)
23872393
} /* switch */
23882394
} /* getast */
23892395

2396+
/** \brief Check if ast is deferred-length character */
2397+
bool
2398+
is_deferlenchar_ast(int ast)
2399+
{
2400+
DTYPE dt;
2401+
SPTR sym = 0;
2402+
2403+
dt = DDTG(A_DTYPEG(ast));
2404+
if (DTY(dt) != TY_CHAR && DTY(dt) != TY_NCHAR) {
2405+
return false;
2406+
}
2407+
2408+
if (dt == DT_ASSCHAR || dt == DT_ASSNCHAR) {
2409+
return false;
2410+
} else if (dt == DT_DEFERCHAR || dt == DT_DEFERNCHAR) {
2411+
return true;
2412+
}
2413+
2414+
if (ast_is_sym(ast)) {
2415+
sym = memsym_of_ast(ast);
2416+
}
2417+
2418+
/* adjustable length character */
2419+
if ((sym > NOSYM) && ADJLENG(sym)) {
2420+
return false;
2421+
}
2422+
2423+
if (DTY(A_DTYPEG(ast)) == TY_ARRAY) {
2424+
if (ADD_DEFER(A_DTYPEG(ast))) {
2425+
dt = DTY(DDTG(A_DTYPEG(ast)) + 1);
2426+
if (A_TYPEG(dt) != A_CNST) {
2427+
return true;
2428+
}
2429+
}
2430+
}
2431+
return false;
2432+
}
2433+
2434+
/** \brief Check if dtype is deferred-length character */
2435+
bool
2436+
is_deferlenchar_dtype(DTYPE dtype)
2437+
{
2438+
DTYPE dt;
2439+
2440+
dt = DDTG(dtype);
2441+
if (DTY(dt) != TY_CHAR && DTY(dt) != TY_NCHAR) {
2442+
return false;
2443+
}
2444+
2445+
if (dt == DT_DEFERCHAR || dt == DT_DEFERNCHAR) {
2446+
return true;
2447+
}
2448+
dt = DTY(dt+1);
2449+
if (DTY(dtype) == TY_ARRAY) {
2450+
if (!ADD_DEFER(dtype)) {
2451+
return false;
2452+
}
2453+
}
2454+
2455+
if (A_TYPEG(dt) == A_ID) {
2456+
/* i.e. character(len=newlen) */
2457+
if (ASSNG(A_SPTRG(dt))) {
2458+
return true;
2459+
}
2460+
} else if (A_TYPEG(dt) == A_SUBSCR) {
2461+
/* i.e. character(len=newlen(1)) */
2462+
if (ASSNG(memsym_of_ast(dt))) {
2463+
return true;
2464+
}
2465+
}
2466+
2467+
/* i.e. character(len=len(a)) */
2468+
if ((A_TYPEG(dt) == A_FUNC || A_TYPEG(dt) == A_INTR)
2469+
&& is_deferlenchar_ast(ARGT_ARG(A_ARGSG(dt), 0))) {
2470+
return true;
2471+
}
2472+
return false;
2473+
}
2474+
2475+
23902476
/** \brief Put into the character array pointed to by ptr, the print
23912477
representation
23922478
of dtype.

tools/flang1/flang1exe/dtypeutl.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
2+
* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -111,3 +111,5 @@ SPTR get_struct_members(DTYPE dtype);
111111
SPTR get_struct_initialization_tree(DTYPE dtype);
112112
LOGICAL is_unresolved_parameterized_dtype(DTYPE dtype);
113113
DTYPE change_assumed_char_to_deferred(DTYPE);
114+
bool is_deferlenchar_ast(int);
115+
bool is_deferlenchar_dtype(DTYPE);

tools/flang1/flang1exe/lowersym.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ static void lower_fileinfo_llvm();
101101
static LOGICAL llvm_iface_flag = FALSE;
102102
static void stb_lower_sym_header();
103103

104+
/** \brief
105+
* ASSCHAR = -1 assumed size character
106+
* ADJCHAR = -2 backend maps to DT_ASSCHAR
107+
* DEFERCHAR = -3 deferred-length character */
108+
enum LEN {ASSCHAR = -1, ADJCHAR = -2, DEFERCHAR = -3};
109+
104110
/** \brief Returns true if the procedure (sptr) has optional arguments.
105111
*/
106112
static bool
@@ -2433,7 +2439,7 @@ eval_con_expr(int ast, int *val, int *dtyp)
24332439
static void
24342440
lower_put_datatype(int dtype, int usage)
24352441
{
2436-
int ndim, i, sptr, zbase, numelm;
2442+
int ndim, i, zbase, numelm;
24372443
int dty, iface;
24382444
/* if this was a 'stashed' old datatype */
24392445
if (DTY(dtype) < 0)
@@ -2586,9 +2592,9 @@ lower_put_datatype(int dtype, int usage)
25862592
case TY_CHAR:
25872593
putwhich("character", "c");
25882594
if (dtype == DT_ASSCHAR) {
2589-
putval("len", -1);
2595+
putval("len", ASSCHAR);
25902596
} else if (dtype == DT_DEFERCHAR) {
2591-
putval("len", -3);
2597+
putval("len", DEFERCHAR);
25922598
} else {
25932599
int clen = DTY(dtype + 1);
25942600
if (A_ALIASG(clen)) {
@@ -2597,16 +2603,20 @@ lower_put_datatype(int dtype, int usage)
25972603
clen = CONVAL2G(clen);
25982604
putval("len", clen);
25992605
} else {
2600-
putval("len", -2 /* which backend maps to DT_ASSCHAR */);
2606+
if (sem.gcvlen && is_deferlenchar_dtype(dtype)) {
2607+
putval("len", DEFERCHAR);
2608+
} else {
2609+
putval("len", ADJCHAR);
2610+
}
26012611
}
26022612
}
26032613
break;
26042614
case TY_NCHAR:
26052615
putwhich("kcharacter", "k");
26062616
if (dtype == DT_ASSNCHAR) {
2607-
putval("len", -1);
2617+
putval("len", ASSCHAR);
26082618
} else if (dtype == DT_DEFERNCHAR) {
2609-
putval("len", -3);
2619+
putval("len", DEFERCHAR);
26102620
} else {
26112621
int clen = DTY(dtype + 1);
26122622
if (A_ALIASG(clen)) {
@@ -2615,7 +2625,7 @@ lower_put_datatype(int dtype, int usage)
26152625
clen = CONVAL2G(clen);
26162626
putval("len", clen);
26172627
} else {
2618-
putval("len", -1);
2628+
putval("len", ASSCHAR);
26192629
}
26202630
}
26212631
break;

tools/flang1/flang1exe/semutil2.c

Lines changed: 58 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -751,19 +751,6 @@ add_p_dealloc_item(int sptr)
751751
sem.p_dealloc = itemp;
752752
}
753753

754-
/** \brief Given an allocatable array and an explicit shape list which has been
755-
deposited in the semant 'bounds' structure, generate assignments to
756-
the arrays bounds temporaries, and allocate the array. Save the id
757-
ast
758-
of the array for an ensuing deallocate of the array.
759-
*/
760-
void
761-
gen_allocate_array(int arr)
762-
{
763-
int alloc_obj = gen_defer_shape(arr, 0, arr);
764-
(void)gen_alloc_dealloc(TK_ALLOCATE, alloc_obj, 0);
765-
add_p_dealloc_item(arr);
766-
}
767754

768755
/** \brief Generate deallocates for the temporary arrays in the sem.p_delloc
769756
* list.
@@ -1011,7 +998,6 @@ typedef struct {
1011998
} _ACS;
1012999

10131000
static _ACS acs;
1014-
10151001
static LOGICAL _can_fold(int);
10161002
static void constructf90(int, ACL *);
10171003
static void _dinit_acl(ACL *, LOGICAL);
@@ -1033,6 +1019,24 @@ iexpr_op(int op)
10331019
return "?N?";
10341020
}
10351021

1022+
/** \brief Given an allocatable array and an explicit shape list which has been
1023+
deposited in the semant 'bounds' structure, generate assignments to
1024+
the arrays bounds temporaries, and allocate the array. Save the id
1025+
ast
1026+
of the array for an ensuing deallocate of the array.
1027+
*/
1028+
void
1029+
gen_allocate_array(int arr)
1030+
{
1031+
int alloc_obj = gen_defer_shape(arr, 0, arr);
1032+
if (is_deferlenchar_dtype(acs.arrtype)) {
1033+
get_static_descriptor(arr);
1034+
get_all_descriptors(arr);
1035+
}
1036+
gen_alloc_dealloc(TK_ALLOCATE, alloc_obj, 0);
1037+
add_p_dealloc_item(arr);
1038+
}
1039+
10361040
#if DEBUG
10371041
static void
10381042
_printacl(int in_array, ACL *aclp, FILE *f)
@@ -1491,6 +1495,9 @@ chk_constructor(ACL *aclp, DTYPE dtype)
14911495
sem.arrdim.ndefer = 1;
14921496
acs.is_const = FALSE;
14931497
}
1498+
if (sem.gcvlen && is_deferlenchar_dtype(acs.eltype)) {
1499+
sem.arrdim.ndefer = 1;
1500+
}
14941501
aclp->size = sem.bounds[0].upast;
14951502

14961503
acs.arrtype = mk_arrdsc();
@@ -1669,6 +1676,7 @@ init_sptr_w_acl(int in_sptr, ACL *aclp)
16691676
if (sem.arrdim.ndefer) {
16701677
ALLOCATE_ARRAYS = 0; /* allocate for these array temps is done here */
16711678
}
1679+
16721680
sptr = acs.tmp = get_arr_temp(acs.arrtype, FALSE, FALSE, FALSE);
16731681
ALLOCATE_ARRAYS = 1;
16741682
if (sem.arrdim.ndefer) {
@@ -1767,13 +1775,17 @@ compute_size_ast(bool add_flag, ACL *aclp, DTYPE dtype)
17671775
static DTYPE
17681776
compute_size_expr(bool add_flag, ACL *aclp, DTYPE dtype)
17691777
{
1778+
DTYPE dt2, dtype2;
17701779
SST *stkp = aclp->u1.stkp;
17711780
LOGICAL specified_dtype = dtype != 0;
1772-
DTYPE dt = dtype;
1781+
DTYPE dt = DDTG(dtype);
1782+
dtype2 = SST_DTYPEG(stkp);
1783+
dt2 = DDTG(SST_DTYPEG(stkp));
17731784
if (!specified_dtype) {
1774-
dtype = SST_DTYPEG(stkp);
1775-
dt = DDTG(dtype);
1785+
dtype = dtype2;
1786+
dt = dt2;
17761787
}
1788+
17771789
if (acs.eltype == 0 || acs.zln) {
17781790
int id = SST_IDG(stkp);
17791791
if (acs.eltype != 0) {
@@ -1786,15 +1798,21 @@ compute_size_expr(bool add_flag, ACL *aclp, DTYPE dtype)
17861798
|| dtype == DT_ASSNCHAR || dtype == DT_DEFERNCHAR
17871799
) {
17881800
dt = adjust_ch_length(dt, SST_ASTG(stkp));
1801+
} else if (dt == DT_ASSCHAR || dt == DT_DEFERCHAR
1802+
|| dt == DT_ASSNCHAR || dt == DT_DEFERNCHAR
1803+
) {
1804+
dt = fix_dtype(SST_SYMG(stkp), dt);
17891805
}
17901806
}
17911807
/* need to change the type for the first element too */
17921808
if (specified_dtype && acs.eltype == 0 &&
17931809
add_flag) { /* if we're in a struct, don't do */
17941810
if (DTY(dt) == TY_CHAR && DTY(dtype) == TY_CHAR)
1795-
;
1811+
if (dtype2 != DT_DEFERCHAR && dtype2 != DT_DEFERNCHAR)
1812+
dtype = SST_DTYPEG(stkp);
17961813
else if (DTY(dt) == TY_NCHAR && DTY(dtype) == TY_NCHAR)
1797-
;
1814+
if (dtype2 != DT_DEFERCHAR && dtype2 != DT_DEFERNCHAR)
1815+
dtype = SST_DTYPEG(stkp);
17981816
else if (DTY(dtype) == TY_ARRAY) {
17991817
if (DDTG(dtype) != dt) {
18001818
errsev(95);
@@ -1818,10 +1836,12 @@ compute_size_expr(bool add_flag, ACL *aclp, DTYPE dtype)
18181836
* causes S_CONST to become S_EXPR.
18191837
*/
18201838
if (add_flag) { /* if we're in a struct, don't do */
1821-
if (DTY(acs.eltype) == TY_CHAR && DTY(dtype) == TY_CHAR)
1822-
;
1823-
else if (DTY(acs.eltype) == TY_NCHAR && DTY(dtype) == TY_NCHAR)
1824-
;
1839+
if (DTY(dt) == TY_CHAR && DTY(dtype) == TY_CHAR)
1840+
if (dtype2 != DT_DEFERCHAR && dtype2 != DT_DEFERNCHAR)
1841+
dtype = SST_DTYPEG(stkp);
1842+
else if (DTY(dt) == TY_NCHAR && DTY(dtype) == TY_NCHAR)
1843+
if (dtype2 != DT_DEFERCHAR && dtype2 != DT_DEFERNCHAR)
1844+
dtype = SST_DTYPEG(stkp);
18251845
else if (DTY(dtype) == TY_ARRAY) {
18261846
if (!eq_dtype(DDTG(dtype), acs.eltype)) {
18271847
errsev(95);
@@ -2328,6 +2348,9 @@ get_shape_arraydtype(int shape, int eltype)
23282348
}
23292349
}
23302350

2351+
if (is_deferlenchar_dtype(acs.arrtype))
2352+
sem.arrdim.ndefer = 1;
2353+
23312354
arrtype = mk_arrdsc();
23322355
DTY(arrtype + 1) = eltype;
23332356
return arrtype;
@@ -2364,7 +2387,11 @@ mkexpr_assign_temp(SST *stkptr)
23642387
/* if we have an array expression, we need to assign it to
23652388
a temporary so that we can subscript it. */
23662389
if (DTY(dtype = SST_DTYPEG(stkptr)) == TY_ARRAY && !simple) {
2367-
dtype = get_shape_arraydtype(A_SHAPEG(ast), DTY(dtype + 1));
2390+
if (is_deferlenchar_ast(ast)) {
2391+
dtype = get_shape_arraydtype(A_SHAPEG(ast), DTY(acs.arrtype + 1));
2392+
} else {
2393+
dtype = get_shape_arraydtype(A_SHAPEG(ast), DTY(dtype + 1));
2394+
}
23682395
id = get_arr_temp(dtype, FALSE, FALSE, FALSE);
23692396
if (sem.arrdim.ndefer)
23702397
gen_allocate_array(id);
@@ -7605,13 +7632,15 @@ get_ch_temp(DTYPE dtype)
76057632
} while (dt != dtype);
76067633

76077634
if (needalloc) {
7635+
int clen;
76087636
ALLOCP(sptr, 1);
76097637
/* if the length is not a constant, make it 'adjustable' */
7610-
if (A_ALIASG(len) == 0) {
7638+
if (sem.gcvlen && is_deferlenchar_dtype(dtype)) {
7639+
clen = ast_intr(I_LEN, astb.bnd.dtype, 1, mk_id(sptr));
7640+
} else if (A_ALIASG(len) == 0) {
76117641
/* fill in CVLEN field */
76127642
ADJLENP(sptr, 1);
76137643
if (CVLENG(sptr) == 0) {
7614-
int clen;
76157644
clen = sym_get_scalar(SYMNAME(sptr), "len", astb.bnd.dtype);
76167645
CVLENP(sptr, clen);
76177646
}
@@ -7626,7 +7655,8 @@ get_ch_temp(DTYPE dtype)
76267655
if (ADD_LWBD(dtype, d) == 0)
76277656
ADD_LWBD(dtype, d) = astb.bnd.one;
76287657
}
7629-
allocate_temp(sptr);
7658+
if (!ADD_DEFER(DTYPEG(sptr)) || ADJLENG(sptr))
7659+
allocate_temp(sptr);
76307660
}
76317661
} else {
76327662
allocate_temp(sptr);
@@ -11408,8 +11438,7 @@ gen_alloc_dealloc(int stmtyp, int object, ITEM *spec)
1140811438
/* This is for allocate statement, must set length before allocate
1140911439
* sem.gcvlen supposedly gets set only when it is character
1141011440
*/
11411-
if ((DDTG(A_DTYPEG(object)) == DT_DEFERCHAR ||
11412-
DDTG(A_DTYPEG(object)) == DT_DEFERCHAR) &&
11441+
if (is_deferlenchar_ast(object) &&
1141311442
stmtyp == TK_ALLOCATE) {
1141411443
if (sem.gcvlen) {
1141511444
len_stmt =

0 commit comments

Comments
 (0)