1760c2415Smrg /* Miscellaneous stuff that doesn't fit anywhere else.
2*0bfacb9bSmrg    Copyright (C) 2000-2020 Free Software Foundation, Inc.
3760c2415Smrg    Contributed by Andy Vaught
4760c2415Smrg 
5760c2415Smrg This file is part of GCC.
6760c2415Smrg 
7760c2415Smrg GCC is free software; you can redistribute it and/or modify it under
8760c2415Smrg the terms of the GNU General Public License as published by the Free
9760c2415Smrg Software Foundation; either version 3, or (at your option) any later
10760c2415Smrg version.
11760c2415Smrg 
12760c2415Smrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13760c2415Smrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
14760c2415Smrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15760c2415Smrg for more details.
16760c2415Smrg 
17760c2415Smrg You should have received a copy of the GNU General Public License
18760c2415Smrg along with GCC; see the file COPYING3.  If not see
19760c2415Smrg <http://www.gnu.org/licenses/>.  */
20760c2415Smrg 
21760c2415Smrg #include "config.h"
22760c2415Smrg #include "system.h"
23760c2415Smrg #include "coretypes.h"
24760c2415Smrg #include "gfortran.h"
25760c2415Smrg #include "spellcheck.h"
26760c2415Smrg #include "tree.h"
27760c2415Smrg 
28760c2415Smrg 
29760c2415Smrg /* Initialize a typespec to unknown.  */
30760c2415Smrg 
31760c2415Smrg void
gfc_clear_ts(gfc_typespec * ts)32760c2415Smrg gfc_clear_ts (gfc_typespec *ts)
33760c2415Smrg {
34760c2415Smrg   ts->type = BT_UNKNOWN;
35760c2415Smrg   ts->u.derived = NULL;
36760c2415Smrg   ts->kind = 0;
37760c2415Smrg   ts->u.cl = NULL;
38760c2415Smrg   ts->interface = NULL;
39760c2415Smrg   /* flag that says if the type is C interoperable */
40760c2415Smrg   ts->is_c_interop = 0;
41760c2415Smrg   /* says what f90 type the C kind interops with */
42760c2415Smrg   ts->f90_type = BT_UNKNOWN;
43760c2415Smrg   /* flag that says whether it's from iso_c_binding or not */
44760c2415Smrg   ts->is_iso_c = 0;
45760c2415Smrg   ts->deferred = false;
46760c2415Smrg }
47760c2415Smrg 
48760c2415Smrg 
49760c2415Smrg /* Open a file for reading.  */
50760c2415Smrg 
51760c2415Smrg FILE *
gfc_open_file(const char * name)52760c2415Smrg gfc_open_file (const char *name)
53760c2415Smrg {
54760c2415Smrg   if (!*name)
55760c2415Smrg     return stdin;
56760c2415Smrg 
57760c2415Smrg   return fopen (name, "r");
58760c2415Smrg }
59760c2415Smrg 
60760c2415Smrg 
61760c2415Smrg /* Return a string for each type.  */
62760c2415Smrg 
63760c2415Smrg const char *
gfc_basic_typename(bt type)64760c2415Smrg gfc_basic_typename (bt type)
65760c2415Smrg {
66760c2415Smrg   const char *p;
67760c2415Smrg 
68760c2415Smrg   switch (type)
69760c2415Smrg     {
70760c2415Smrg     case BT_INTEGER:
71760c2415Smrg       p = "INTEGER";
72760c2415Smrg       break;
73760c2415Smrg     case BT_REAL:
74760c2415Smrg       p = "REAL";
75760c2415Smrg       break;
76760c2415Smrg     case BT_COMPLEX:
77760c2415Smrg       p = "COMPLEX";
78760c2415Smrg       break;
79760c2415Smrg     case BT_LOGICAL:
80760c2415Smrg       p = "LOGICAL";
81760c2415Smrg       break;
82760c2415Smrg     case BT_CHARACTER:
83760c2415Smrg       p = "CHARACTER";
84760c2415Smrg       break;
85760c2415Smrg     case BT_HOLLERITH:
86760c2415Smrg       p = "HOLLERITH";
87760c2415Smrg       break;
88760c2415Smrg     case BT_UNION:
89760c2415Smrg       p = "UNION";
90760c2415Smrg       break;
91760c2415Smrg     case BT_DERIVED:
92760c2415Smrg       p = "DERIVED";
93760c2415Smrg       break;
94760c2415Smrg     case BT_CLASS:
95760c2415Smrg       p = "CLASS";
96760c2415Smrg       break;
97760c2415Smrg     case BT_PROCEDURE:
98760c2415Smrg       p = "PROCEDURE";
99760c2415Smrg       break;
100760c2415Smrg     case BT_VOID:
101760c2415Smrg       p = "VOID";
102760c2415Smrg       break;
103*0bfacb9bSmrg     case BT_BOZ:
104*0bfacb9bSmrg       p = "BOZ";
105*0bfacb9bSmrg       break;
106760c2415Smrg     case BT_UNKNOWN:
107760c2415Smrg       p = "UNKNOWN";
108760c2415Smrg       break;
109760c2415Smrg     case BT_ASSUMED:
110760c2415Smrg       p = "TYPE(*)";
111760c2415Smrg       break;
112760c2415Smrg     default:
113760c2415Smrg       gfc_internal_error ("gfc_basic_typename(): Undefined type");
114760c2415Smrg     }
115760c2415Smrg 
116760c2415Smrg   return p;
117760c2415Smrg }
118760c2415Smrg 
119760c2415Smrg 
120760c2415Smrg /* Return a string describing the type and kind of a typespec.  Because
121760c2415Smrg    we return alternating buffers, this subroutine can appear twice in
122760c2415Smrg    the argument list of a single statement.  */
123760c2415Smrg 
124760c2415Smrg const char *
gfc_typename(gfc_typespec * ts,bool for_hash)125*0bfacb9bSmrg gfc_typename (gfc_typespec *ts, bool for_hash)
126760c2415Smrg {
127760c2415Smrg   static char buffer1[GFC_MAX_SYMBOL_LEN + 7];  /* 7 for "TYPE()" + '\0'.  */
128760c2415Smrg   static char buffer2[GFC_MAX_SYMBOL_LEN + 7];
129760c2415Smrg   static int flag = 0;
130760c2415Smrg   char *buffer;
131760c2415Smrg   gfc_typespec *ts1;
132*0bfacb9bSmrg   gfc_charlen_t length = 0;
133760c2415Smrg 
134760c2415Smrg   buffer = flag ? buffer1 : buffer2;
135760c2415Smrg   flag = !flag;
136760c2415Smrg 
137760c2415Smrg   switch (ts->type)
138760c2415Smrg     {
139760c2415Smrg     case BT_INTEGER:
140760c2415Smrg       sprintf (buffer, "INTEGER(%d)", ts->kind);
141760c2415Smrg       break;
142760c2415Smrg     case BT_REAL:
143760c2415Smrg       sprintf (buffer, "REAL(%d)", ts->kind);
144760c2415Smrg       break;
145760c2415Smrg     case BT_COMPLEX:
146760c2415Smrg       sprintf (buffer, "COMPLEX(%d)", ts->kind);
147760c2415Smrg       break;
148760c2415Smrg     case BT_LOGICAL:
149760c2415Smrg       sprintf (buffer, "LOGICAL(%d)", ts->kind);
150760c2415Smrg       break;
151760c2415Smrg     case BT_CHARACTER:
152*0bfacb9bSmrg       if (for_hash)
153*0bfacb9bSmrg 	{
154760c2415Smrg 	  sprintf (buffer, "CHARACTER(%d)", ts->kind);
155760c2415Smrg 	  break;
156*0bfacb9bSmrg 	}
157*0bfacb9bSmrg 
158*0bfacb9bSmrg       if (ts->u.cl && ts->u.cl->length)
159*0bfacb9bSmrg 	length = gfc_mpz_get_hwi (ts->u.cl->length->value.integer);
160*0bfacb9bSmrg       if (ts->kind == gfc_default_character_kind)
161*0bfacb9bSmrg 	sprintf (buffer, "CHARACTER(" HOST_WIDE_INT_PRINT_DEC ")", length);
162*0bfacb9bSmrg       else
163*0bfacb9bSmrg 	sprintf (buffer, "CHARACTER(" HOST_WIDE_INT_PRINT_DEC ",%d)", length,
164*0bfacb9bSmrg 		 ts->kind);
165*0bfacb9bSmrg       break;
166760c2415Smrg     case BT_HOLLERITH:
167760c2415Smrg       sprintf (buffer, "HOLLERITH");
168760c2415Smrg       break;
169760c2415Smrg     case BT_UNION:
170760c2415Smrg       sprintf (buffer, "UNION(%s)", ts->u.derived->name);
171760c2415Smrg       break;
172760c2415Smrg     case BT_DERIVED:
173*0bfacb9bSmrg       if (ts->u.derived == NULL)
174*0bfacb9bSmrg 	{
175*0bfacb9bSmrg 	  sprintf (buffer, "invalid type");
176*0bfacb9bSmrg 	  break;
177*0bfacb9bSmrg 	}
178760c2415Smrg       sprintf (buffer, "TYPE(%s)", ts->u.derived->name);
179760c2415Smrg       break;
180760c2415Smrg     case BT_CLASS:
181*0bfacb9bSmrg       if (ts->u.derived == NULL)
182*0bfacb9bSmrg 	{
183*0bfacb9bSmrg 	  sprintf (buffer, "invalid class");
184*0bfacb9bSmrg 	  break;
185*0bfacb9bSmrg 	}
186760c2415Smrg       ts1 = ts->u.derived->components ? &ts->u.derived->components->ts : NULL;
187760c2415Smrg       if (ts1 && ts1->u.derived && ts1->u.derived->attr.unlimited_polymorphic)
188760c2415Smrg 	sprintf (buffer, "CLASS(*)");
189760c2415Smrg       else
190760c2415Smrg 	sprintf (buffer, "CLASS(%s)", ts->u.derived->name);
191760c2415Smrg       break;
192760c2415Smrg     case BT_ASSUMED:
193760c2415Smrg       sprintf (buffer, "TYPE(*)");
194760c2415Smrg       break;
195760c2415Smrg     case BT_PROCEDURE:
196760c2415Smrg       strcpy (buffer, "PROCEDURE");
197760c2415Smrg       break;
198*0bfacb9bSmrg     case BT_BOZ:
199*0bfacb9bSmrg       strcpy (buffer, "BOZ");
200*0bfacb9bSmrg       break;
201760c2415Smrg     case BT_UNKNOWN:
202760c2415Smrg       strcpy (buffer, "UNKNOWN");
203760c2415Smrg       break;
204760c2415Smrg     default:
205760c2415Smrg       gfc_internal_error ("gfc_typename(): Undefined type");
206760c2415Smrg     }
207760c2415Smrg 
208760c2415Smrg   return buffer;
209760c2415Smrg }
210760c2415Smrg 
211760c2415Smrg 
212*0bfacb9bSmrg const char *
gfc_typename(gfc_expr * ex)213*0bfacb9bSmrg gfc_typename (gfc_expr *ex)
214*0bfacb9bSmrg {
215*0bfacb9bSmrg   /* 34 character buffer: 14 for "CHARACTER(n,4)", n can be upto 20 characters,
216*0bfacb9bSmrg      add 19 for the extra width and 1 for '\0' */
217*0bfacb9bSmrg   static char buffer1[34];
218*0bfacb9bSmrg   static char buffer2[34];
219*0bfacb9bSmrg   static bool flag = false;
220*0bfacb9bSmrg   char *buffer;
221*0bfacb9bSmrg   gfc_charlen_t length;
222*0bfacb9bSmrg   buffer = flag ? buffer1 : buffer2;
223*0bfacb9bSmrg   flag = !flag;
224*0bfacb9bSmrg 
225*0bfacb9bSmrg   if (ex->ts.type == BT_CHARACTER)
226*0bfacb9bSmrg     {
227*0bfacb9bSmrg       if (ex->expr_type == EXPR_CONSTANT)
228*0bfacb9bSmrg 	length = ex->value.character.length;
229*0bfacb9bSmrg       else if (ex->ts.deferred)
230*0bfacb9bSmrg 	{
231*0bfacb9bSmrg 	  if (ex->ts.kind == gfc_default_character_kind)
232*0bfacb9bSmrg 	    return "CHARACTER(:)";
233*0bfacb9bSmrg 	  sprintf (buffer, "CHARACTER(:,%d)", ex->ts.kind);
234*0bfacb9bSmrg 	  return buffer;
235*0bfacb9bSmrg 	}
236*0bfacb9bSmrg       else if (ex->ts.u.cl && ex->ts.u.cl->length == NULL)
237*0bfacb9bSmrg 	{
238*0bfacb9bSmrg 	  if (ex->ts.kind == gfc_default_character_kind)
239*0bfacb9bSmrg 	    return "CHARACTER(*)";
240*0bfacb9bSmrg 	  sprintf (buffer, "CHARACTER(*,%d)", ex->ts.kind);
241*0bfacb9bSmrg 	  return buffer;
242*0bfacb9bSmrg 	}
243*0bfacb9bSmrg       else if (ex->ts.u.cl == NULL
244*0bfacb9bSmrg 	       || ex->ts.u.cl->length->expr_type != EXPR_CONSTANT)
245*0bfacb9bSmrg 	{
246*0bfacb9bSmrg 	  if (ex->ts.kind == gfc_default_character_kind)
247*0bfacb9bSmrg 	    return "CHARACTER";
248*0bfacb9bSmrg 	  sprintf (buffer, "CHARACTER(KIND=%d)", ex->ts.kind);
249*0bfacb9bSmrg 	  return buffer;
250*0bfacb9bSmrg 	}
251*0bfacb9bSmrg       else
252*0bfacb9bSmrg 	length = gfc_mpz_get_hwi (ex->ts.u.cl->length->value.integer);
253*0bfacb9bSmrg       if (ex->ts.kind == gfc_default_character_kind)
254*0bfacb9bSmrg 	sprintf (buffer, "CHARACTER(" HOST_WIDE_INT_PRINT_DEC ")", length);
255*0bfacb9bSmrg       else
256*0bfacb9bSmrg 	sprintf (buffer, "CHARACTER(" HOST_WIDE_INT_PRINT_DEC ",%d)", length,
257*0bfacb9bSmrg 		 ex->ts.kind);
258*0bfacb9bSmrg       return buffer;
259*0bfacb9bSmrg     }
260*0bfacb9bSmrg   return gfc_typename(&ex->ts);
261*0bfacb9bSmrg }
262*0bfacb9bSmrg 
263*0bfacb9bSmrg /* The type of a dummy variable can also be CHARACTER(*).  */
264*0bfacb9bSmrg 
265*0bfacb9bSmrg const char *
gfc_dummy_typename(gfc_typespec * ts)266*0bfacb9bSmrg gfc_dummy_typename (gfc_typespec *ts)
267*0bfacb9bSmrg {
268*0bfacb9bSmrg   static char buffer1[15];  /* 15 for "CHARACTER(*,4)" + '\0'.  */
269*0bfacb9bSmrg   static char buffer2[15];
270*0bfacb9bSmrg   static bool flag = false;
271*0bfacb9bSmrg   char *buffer;
272*0bfacb9bSmrg 
273*0bfacb9bSmrg   buffer = flag ? buffer1 : buffer2;
274*0bfacb9bSmrg   flag = !flag;
275*0bfacb9bSmrg 
276*0bfacb9bSmrg   if (ts->type == BT_CHARACTER)
277*0bfacb9bSmrg     {
278*0bfacb9bSmrg       bool has_length = false;
279*0bfacb9bSmrg       if (ts->u.cl)
280*0bfacb9bSmrg 	has_length = ts->u.cl->length != NULL;
281*0bfacb9bSmrg       if (!has_length)
282*0bfacb9bSmrg 	{
283*0bfacb9bSmrg 	  if (ts->kind == gfc_default_character_kind)
284*0bfacb9bSmrg 	    sprintf(buffer, "CHARACTER(*)");
285*0bfacb9bSmrg 	  else if (ts->kind < 10)
286*0bfacb9bSmrg 	    sprintf(buffer, "CHARACTER(*,%d)", ts->kind);
287*0bfacb9bSmrg 	  else
288*0bfacb9bSmrg 	    sprintf(buffer, "CHARACTER(*,?)");
289*0bfacb9bSmrg 	  return buffer;
290*0bfacb9bSmrg 	}
291*0bfacb9bSmrg     }
292*0bfacb9bSmrg   return gfc_typename(ts);
293*0bfacb9bSmrg }
294*0bfacb9bSmrg 
295*0bfacb9bSmrg 
296760c2415Smrg /* Given an mstring array and a code, locate the code in the table,
297760c2415Smrg    returning a pointer to the string.  */
298760c2415Smrg 
299760c2415Smrg const char *
gfc_code2string(const mstring * m,int code)300760c2415Smrg gfc_code2string (const mstring *m, int code)
301760c2415Smrg {
302760c2415Smrg   while (m->string != NULL)
303760c2415Smrg     {
304760c2415Smrg       if (m->tag == code)
305760c2415Smrg 	return m->string;
306760c2415Smrg       m++;
307760c2415Smrg     }
308760c2415Smrg 
309760c2415Smrg   gfc_internal_error ("gfc_code2string(): Bad code");
310760c2415Smrg   /* Not reached */
311760c2415Smrg }
312760c2415Smrg 
313760c2415Smrg 
314760c2415Smrg /* Given an mstring array and a string, returns the value of the tag
315760c2415Smrg    field.  Returns the final tag if no matches to the string are found.  */
316760c2415Smrg 
317760c2415Smrg int
gfc_string2code(const mstring * m,const char * string)318760c2415Smrg gfc_string2code (const mstring *m, const char *string)
319760c2415Smrg {
320760c2415Smrg   for (; m->string != NULL; m++)
321760c2415Smrg     if (strcmp (m->string, string) == 0)
322760c2415Smrg       return m->tag;
323760c2415Smrg 
324760c2415Smrg   return m->tag;
325760c2415Smrg }
326760c2415Smrg 
327760c2415Smrg 
328760c2415Smrg /* Convert an intent code to a string.  */
329760c2415Smrg /* TODO: move to gfortran.h as define.  */
330760c2415Smrg 
331760c2415Smrg const char *
gfc_intent_string(sym_intent i)332760c2415Smrg gfc_intent_string (sym_intent i)
333760c2415Smrg {
334760c2415Smrg   return gfc_code2string (intents, i);
335760c2415Smrg }
336760c2415Smrg 
337760c2415Smrg 
338760c2415Smrg /***************** Initialization functions ****************/
339760c2415Smrg 
340760c2415Smrg /* Top level initialization.  */
341760c2415Smrg 
342760c2415Smrg void
gfc_init_1(void)343760c2415Smrg gfc_init_1 (void)
344760c2415Smrg {
345760c2415Smrg   gfc_error_init_1 ();
346760c2415Smrg   gfc_scanner_init_1 ();
347760c2415Smrg   gfc_arith_init_1 ();
348760c2415Smrg   gfc_intrinsic_init_1 ();
349760c2415Smrg }
350760c2415Smrg 
351760c2415Smrg 
352760c2415Smrg /* Per program unit initialization.  */
353760c2415Smrg 
354760c2415Smrg void
gfc_init_2(void)355760c2415Smrg gfc_init_2 (void)
356760c2415Smrg {
357760c2415Smrg   gfc_symbol_init_2 ();
358760c2415Smrg   gfc_module_init_2 ();
359760c2415Smrg }
360760c2415Smrg 
361760c2415Smrg 
362760c2415Smrg /******************* Destructor functions ******************/
363760c2415Smrg 
364760c2415Smrg /* Call all of the top level destructors.  */
365760c2415Smrg 
366760c2415Smrg void
gfc_done_1(void)367760c2415Smrg gfc_done_1 (void)
368760c2415Smrg {
369760c2415Smrg   gfc_scanner_done_1 ();
370760c2415Smrg   gfc_intrinsic_done_1 ();
371760c2415Smrg   gfc_arith_done_1 ();
372760c2415Smrg }
373760c2415Smrg 
374760c2415Smrg 
375760c2415Smrg /* Per program unit destructors.  */
376760c2415Smrg 
377760c2415Smrg void
gfc_done_2(void)378760c2415Smrg gfc_done_2 (void)
379760c2415Smrg {
380760c2415Smrg   gfc_symbol_done_2 ();
381760c2415Smrg   gfc_module_done_2 ();
382760c2415Smrg }
383760c2415Smrg 
384760c2415Smrg 
385760c2415Smrg /* Returns the index into the table of C interoperable kinds where the
386760c2415Smrg    kind with the given name (c_kind_name) was found.  */
387760c2415Smrg 
388760c2415Smrg int
get_c_kind(const char * c_kind_name,CInteropKind_t kinds_table[])389760c2415Smrg get_c_kind(const char *c_kind_name, CInteropKind_t kinds_table[])
390760c2415Smrg {
391760c2415Smrg   int index = 0;
392760c2415Smrg 
393760c2415Smrg   for (index = 0; index < ISOCBINDING_LAST; index++)
394760c2415Smrg     if (strcmp (kinds_table[index].name, c_kind_name) == 0)
395760c2415Smrg       return index;
396760c2415Smrg 
397760c2415Smrg   return ISOCBINDING_INVALID;
398760c2415Smrg }
399760c2415Smrg 
400760c2415Smrg 
401760c2415Smrg /* For a given name TYPO, determine the best candidate from CANDIDATES
402760c2415Smrg    using get_edit_distance.  Frees CANDIDATES before returning.  */
403760c2415Smrg 
404760c2415Smrg const char *
gfc_closest_fuzzy_match(const char * typo,char ** candidates)405760c2415Smrg gfc_closest_fuzzy_match (const char *typo, char **candidates)
406760c2415Smrg {
407760c2415Smrg   /* Determine closest match.  */
408760c2415Smrg   const char *best = NULL;
409760c2415Smrg   char **cand = candidates;
410760c2415Smrg   edit_distance_t best_distance = MAX_EDIT_DISTANCE;
411760c2415Smrg   const size_t tl = strlen (typo);
412760c2415Smrg 
413760c2415Smrg   while (cand && *cand)
414760c2415Smrg     {
415760c2415Smrg       edit_distance_t dist = get_edit_distance (typo, tl, *cand,
416760c2415Smrg 	  strlen (*cand));
417760c2415Smrg       if (dist < best_distance)
418760c2415Smrg 	{
419760c2415Smrg 	   best_distance = dist;
420760c2415Smrg 	   best = *cand;
421760c2415Smrg 	}
422760c2415Smrg       cand++;
423760c2415Smrg     }
424760c2415Smrg   /* If more than half of the letters were misspelled, the suggestion is
425760c2415Smrg      likely to be meaningless.  */
426760c2415Smrg   if (best)
427760c2415Smrg     {
428760c2415Smrg       unsigned int cutoff = MAX (tl, strlen (best)) / 2;
429760c2415Smrg 
430760c2415Smrg       if (best_distance > cutoff)
431760c2415Smrg 	{
432760c2415Smrg 	  XDELETEVEC (candidates);
433760c2415Smrg 	  return NULL;
434760c2415Smrg 	}
435760c2415Smrg       XDELETEVEC (candidates);
436760c2415Smrg     }
437760c2415Smrg   return best;
438760c2415Smrg }
439760c2415Smrg 
440760c2415Smrg /* Convert between GMP integers (mpz_t) and HOST_WIDE_INT.  */
441760c2415Smrg 
442760c2415Smrg HOST_WIDE_INT
gfc_mpz_get_hwi(mpz_t op)443760c2415Smrg gfc_mpz_get_hwi (mpz_t op)
444760c2415Smrg {
445760c2415Smrg   /* Using long_long_integer_type_node as that is the integer type
446760c2415Smrg      node that closest matches HOST_WIDE_INT; both are guaranteed to
447760c2415Smrg      be at least 64 bits.  */
448760c2415Smrg   const wide_int w = wi::from_mpz (long_long_integer_type_node, op, true);
449760c2415Smrg   return w.to_shwi ();
450760c2415Smrg }
451760c2415Smrg 
452760c2415Smrg 
453760c2415Smrg void
gfc_mpz_set_hwi(mpz_t rop,const HOST_WIDE_INT op)454760c2415Smrg gfc_mpz_set_hwi (mpz_t rop, const HOST_WIDE_INT op)
455760c2415Smrg {
456760c2415Smrg   const wide_int w = wi::shwi (op, HOST_BITS_PER_WIDE_INT);
457760c2415Smrg   wi::to_mpz (w, rop, SIGNED);
458760c2415Smrg }
459