OpenADFortTk (including Open64 and OpenAnalysis references)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ty2xaif.cxx
Go to the documentation of this file.
1 // ##########################################################
2 // # This file is part of OpenADFortTk. #
3 // # The full COPYRIGHT notice can be found in the top #
4 // # level directory of the OpenADFortTk source tree. #
5 // # For more information visit #
6 // # http://www.mcs.anl.gov/openad #
7 // ##########################################################
8 
9 #include <sstream>
10 
12 
13 #include "wn2xaif.h"
14 #include "wn2xaif_mem.h"
15 #include "st2xaif.h"
16 #include "ty2xaif.h"
17 
18 namespace whirl2xaif {
19 
20  extern WN* PU_Body;
21  extern BOOL Array_Bnd_Temp_Var;
22 
23  /* TY2F_Handler[] maps a TY_kind to a function that translates
24  * a type of the given kind into Fortran. Should the ordinal
25  * numbering of the KIND change in "../common/com/stab.h", then
26  * a corresponding change must be made here.
27  */
28 
30 
31  static void
33  static void
35  static void
37  static void
39  static void
41  static void
43  static void
45  static void
47 
48  // ***************************************************************************
49 
50  static const TY2F_HANDLER_FUNC TY2F_Handler[KIND_LAST/*TY_KIND*/] = {
51  &TY2F_invalid, /* KIND_INVALID */
52  &TY2F_scalar, /* KIND_SCALAR */
53  &TY2F_array, /* KIND_ARRAY */
54  &TY2F_struct, /* KIND_STRUCT */
55  &TY2F_pointer, /* KIND_POINTER */
56  &TY2F_invalid, /* KIND_FUNCTION */
57  &TY2F_void, /* KIND_VOID */
58  }; /* TY2F_Handler */
59 
60  /* detect parts of f90 dope vectors which should be output. Most are
61  I4 boundaries except the bofst >16 - just for num_dims */
62 #define NOT_BITFIELD_OR_IS_FIRST_OF_BITFIELD(f) \
63  (!FLD_is_bit_field(f) || (FLD_is_bit_field(f) && (FLD_bofst(f) == 0) || FLD_bofst(f) > 16))
64 
65  // ***************************************************************************
66 
67  void
69  {
70  // Dispatch the translation-task to the appropriate handler function.
71  if (!notyapp)
72  TY2F_Handler[TY_kind(Ty_Table[ty])](xos, ty, ctxt);
73  else
74  TY2F_2_struct(xos, ty, ctxt);
75  }
76 
77  void
79  {
80  TY2F_translate(xos, ty, 0, ctxt);
81  }
82 
83 
84  /*---------------------- A few utility routines -----------------------*/
85  /*---------------------------------------------------------------------*/
86 
87  // static void
88  // WN2F_tempvar_rhs(xml::ostream& xos, WN * wn)
89  // {
90  // /* The rhs */
91  // PUXlationContext ctxt;
92  // whirl2xaif::TranslateWN(xos, WN_kid0(wn), ctxt);
93  // }
94 
95  // static void
96  // GetTmpVarTransInfo(xml::ostream& xos, ST_IDX arbnd, WN* wn)
97  // {
98  // WN * stmt;
99  // stmt = WN_first(wn);
100  // while ((stmt !=NULL)
101  // && ((WN_operator(stmt)!=OPR_STID) || (WN_operator(stmt) ==OPR_STID)
102  // && strcmp(ST_name(WN_st(stmt)), ST_name(ST_ptr(arbnd)))))
103  // stmt = WN_next(stmt);
104  // if (stmt != NULL)
105  // WN2F_tempvar_rhs(xos, stmt);
106  // }
107 
108  static std::string
110  {
111  // FIXME:
112  std::ostringstream xos_abdstr;
113  xml::ostream xos_abd(xos_abdstr.rdbuf());
114 
115 #if 0 // FIXME
116  WN* wn = PU_Body; // FIXME--Yuck!!!
117  GetTmpVarTransInfo(xos_abd, arbnd, wn);
118 #endif
119 
120  return xos_abdstr.str();
121  }
122 
123  static void
125  PUXlationContext& ctxt)
126  {
127  if (TY_is_f90_deferred_shape(ty_idx)) {
128 
129  xos << xml::BegElem("xaif:Property") << xml::Attr("id", ctxt.currentXlationContext().getNewVertexId())
130  << xml::Attr("name", "shape") << xml::Attr("value", ':') << xml::EndElem;
131 
132  } else {
133 
134  std::string lb, ub;
135  if (ARB_const_lbnd(arb)) {
137  FALSE /*is_logical*/);
138  } else if (ARB_lbnd_var(arb) != 0) {
140  }
141 
142  if (ARB_const_ubnd(arb)) {
144  FALSE /*is_logical*/);
145  } else if (ARB_ubnd_var(arb) != 0) {
147  }
148 
149  xos << xml::BegElem("xaif:Property") << xml::Attr("id", ctxt.currentXlationContext().getNewVertexId())
150  << xml::Attr("name", "lb") << xml::Attr("value", lb) << xml::EndElem;
151  xos << xml::BegElem("xaif:Property") << xml::Attr("id", ctxt.currentXlationContext().getNewVertexId())
152  << xml::Attr("name", "ub") << xml::Attr("value", ub) << xml::EndElem;
153 
154  }
155  }
156 
157  static BOOL
159  {
160  while (TY_kind(ty) == KIND_ARRAY)
161  ty = TY_etype(ty);
162 
163  return TY_is_character(ty);
164  }
165  /*------ Utilities for accessing and declaring KIND_STRUCT FLDs ------
166  *---------------------------------------------------------------------*/
167 
168 #define FLD_INFO_ALLOC_CHUNK 16
170 
171 
172  static BOOL
174  {
175  /* Is this a pointer to a dope vector base */
176  return (strcmp(TY_name(TY_pointed(ty)),".base.") == 0) ;
177  }
178 
179  static FLD_PATH_INFO *
181  {
182  /* Allocates a new FLD_PATH_INFO, reusing any that have earlier
183  * been freed up. Dynamic allocation occurs in chunks of 16
184  * (FLD_INFO_ALLOC_CHUNK) FLD_PATH_INFOs at a time.
185  */
186  FLD_PATH_INFO *fld_info;
187 
188  if (Free_Fld_Path_Info != NULL)
189  {
190  fld_info = Free_Fld_Path_Info;
191  Free_Fld_Path_Info = fld_info->next;
192  }
193  else
194  {
195  INT info_idx;
196 
197  /* Allocate a new chunk of path infos, and put all except the
198  * first one on the free-list.
199  */
203  for (info_idx = FLD_INFO_ALLOC_CHUNK-2; info_idx > 0; info_idx--)
204  fld_info[info_idx].next = &fld_info[info_idx+1];
205  Free_Fld_Path_Info = &fld_info[1];
206  }
207 
208  fld_info->next = NULL;
209  fld_info->arr_elt = FALSE;
210  fld_info->arr_ofst = 0;
211  fld_info->arr_wn = NULL;
212  fld_info->fld = fld;
213  return fld_info;
214  } /* New_Fld_Path_Info */
215 
216  static STAB_OFFSET
217  TY2F_Fld_Size(FLD_HANDLE this_fld, mUINT64 max_size)
218  {
219  /* Returns the size of the field, taking into account the offset
220  * to the next (non-equivalence) field and the maximum field-size
221  * (based on the structure size).
222  */
223 
224  mUINT64 fld_size = TY_size(FLD_type(this_fld));
225 
226  /* Restrict the fld_size to the max_size */
227  if (fld_size > max_size)
228  fld_size = max_size;
229 
230  /* If this_fld is an equivalence field, then just return the current
231  * fld_size (cannot be any different), otherwise search for a non-
232  * equivalent next_fld at a higher offset.
233  * TODO: mfef90 & mfef77 set the flag slightly differently in COMMON.
234  * this really works only for mfef77.
235  */
236 
237  if (!FLD_equivalence(this_fld))
238  {
239  FLD_ITER fld_iter = Make_fld_iter(this_fld);
240 
241  if (!FLD_last_field (fld_iter))
242  {
243  ++fld_iter;
244  BOOL found = FALSE;
245  mUINT64 noffset = 0;
246 
247  do
248  {
249  FLD_HANDLE next_fld (fld_iter);
250 
251  if (!FLD_is_bit_field(next_fld))
252  if (!(FLD_equivalence(next_fld) || FLD_ofst(this_fld) >= FLD_ofst(next_fld)))
253  {
254  found = TRUE;
255  noffset = FLD_ofst(next_fld) ;
256  break ;
257  }
258  } while (!FLD_last_field (fld_iter ++ )) ;
259 
260  if (found)
261  if (fld_size > noffset - FLD_ofst(this_fld))
262  fld_size = noffset - FLD_ofst(this_fld) ;
263  }
264  }
265  return fld_size;
266  } /* TY2F_Fld_Size */
267 
268 
269  static FLD_PATH_INFO *
271  FLD_PATH_INFO *path2,
272  TY_IDX desired_ty,
273  mUINT64 desired_offset)
274  {
275  /* PRECONDITION: Both paths must be non-NULL and lead to a field
276  * at the desired_offset.
277  *
278  * Try to find the best of two paths to a field. This routine
279  * will be called for EVERY field at every place where a struct,
280  * union, or equivalence field is accessed, so efficiency is of
281  * uttmost importance. The best path is returned, while the other
282  * on is freed up.
283  */
285 
286  FLD_PATH_INFO *best_path;
287  mUINT64 offs1, offs2;
288  FLD_PATH_INFO *p1, *p2;
289  TY_IDX t1, t2;
290 
291  /* Find the last field on each path */
292  offs1 = FLD_ofst(path1->fld) + path1->arr_ofst;
293  for (p1 = path1; p1->next != NULL; p1 = p1->next)
294  offs1 += FLD_ofst(p1->next->fld) + p1->next->arr_ofst;
295  offs2 = FLD_ofst(path2->fld) + path2->arr_ofst;
296  for (p2 = path2; p2->next != NULL; p2 = p2->next)
297  offs2 += FLD_ofst(p2->next->fld) + p2->next->arr_ofst;
298 
299  FORTTK_ASSERT(offs1 == desired_offset && offs2 == desired_offset,
300  "Unexpected offset");
301 
302  /* Get the element type (either the field type or the type of an
303  * array element.
304  */
305  if (p1->arr_elt)
306  t1 = TY_AR_etype(FLD_type(p1->fld));
307  else
308  t1 = FLD_type(p1->fld);
309  if (p2->arr_elt)
310  t2 = TY_AR_etype(FLD_type(p2->fld));
311  else
312  t2 = FLD_type(p2->fld);
313 
314  /* Compare types, in order of increasing accuracy */
315  if (TY_mtype(t1) == TY_mtype(desired_ty) &&
316  TY_mtype(t2) != TY_mtype(desired_ty))
317  best_path = path1;
318  else if (TY_mtype(t2) == TY_mtype(desired_ty) &&
319  TY_mtype(t1) != TY_mtype(desired_ty))
320  best_path = path2;
321  else if (Stab_Identical_Types(t1, desired_ty,
322  FALSE, /* check_quals */
323  TRUE, /* check_scalars */
324  FALSE)) /* ptrs_as_scalars */
325  best_path = path1; /* path2 cannot possibly be any better */
326  else if (Stab_Identical_Types(t2, desired_ty,
327  FALSE, /* check_quals */
328  TRUE, /* check_scalars */
329  FALSE)) /* ptrs_as_scalars */
330  best_path = path2;
331  else
332  best_path = path1;
333 
334  /* Free up the path not chosen */
335  if (best_path == path1)
336  TY2F_Free_Fld_Path(path2);
337  else
338  TY2F_Free_Fld_Path(path1);
339 
340  return best_path;
341  } /* Select_Best_Fld_Path */
342 
343 
344  static FLD_PATH_INFO *
346  TY_IDX struct_ty,
347  TY_IDX desired_ty,
348  mUINT64 desired_offset,
349  mUINT64 max_fld_size)
350  {
351  /* Returns the field path through "fld" found to best match the
352  * given offset and type. As a minimum requirement, the offset
353  * must be as desired and the type must have the desired size
354  * and alignment (with some concessions allowed for substrings).
355  * The path is terminate with a NULL next pointer. When no
356  * field matches the desired type and offset, NULL is returned.
357  */
358  FLD_PATH_INFO *fld_path;
359  const mUINT64 fld_offset = FLD_ofst(fld);
360  TY_IDX fld_ty = FLD_type(fld);
361  BOOL is_array_elt = FALSE;
362  STAB_OFFSET ofst_in_fld = 0;
363 
364  if (TY_is_f90_pointer(fld_ty))
365  fld_ty = TY_pointed(fld_ty);
366 
367 
368  /* This field cannot be on the path to a field with the given
369  * attributes, unless the desired_offset is somewhere within
370  * the field.
371  */
372 #if DBGPATH
373  printf (" Construct: fld %s, struct %s, desired %s , des off %d \n",
374  FLD_name(fld), TY_name(struct_ty), TY_name(desired_ty),
375  desired_offset);
376 #endif
377 
378  if (desired_offset < fld_offset ||
379  desired_offset >= (fld_offset + TY_size(fld_ty))) {
380  /* This field cannot be on the path to a field with the given
381  * attributes, since the desired_offset is nowhere within
382  * the field.
383  */
384  fld_path = NULL;
385 #if DBGPATH
386  printf (" found NULL\n");
387 #endif
388  } else if (TY_Is_Array(fld_ty) && TY_is_character(fld_ty) &&
389  TY_Is_Array(desired_ty) && TY_is_character(desired_ty)) {
390 #if DBGPATH
391  printf (" found char substring\n");
392 #endif
393  /* A match is found! */
394  ofst_in_fld = (desired_offset - fld_offset)/TY_size(TY_AR_etype(fld_ty));
395  ofst_in_fld *= TY_size(TY_AR_etype(fld_ty));
396  if ((ofst_in_fld + TY_size(desired_ty)) > TY_size(fld_ty)) {
397  fld_path = NULL; /* The string does not fit */
398  } else {
399  fld_path = New_Fld_Path_Info(fld);
400  if (TY_size(fld_ty) != TY_size(desired_ty)) {
401  fld_path->arr_elt = TRUE;
402  fld_path->arr_ofst = ofst_in_fld;
403  }
404  }
405  } else {
406  /* See if the field we are looking for may be an array element */
407 
408  if (TY_kind(desired_ty)==KIND_POINTER)
409  desired_ty = TY_pointed(desired_ty);
410  if (TY_kind(desired_ty)==KIND_ARRAY)
411  desired_ty = TY_AR_etype(desired_ty);
412 
413  is_array_elt = (TY_Is_Array(fld_ty) &&
414  (TY_Is_Structured(TY_AR_etype(fld_ty))||
415  TY2F_is_character(fld_ty) ||
416  Stab_Identical_Types(TY_AR_etype(fld_ty), desired_ty,
417  FALSE, /* check_quals */
418  FALSE, /* check_scalars */
419  TRUE))); /* ptrs_as_scalars */
420 #if DBGPATH
421  printf (" is_array = %d, fld_ty %s \n",is_array_elt,TY_name(fld_ty));
422 #endif
423 
424  if (is_array_elt) {
425  fld_ty = TY_AR_etype(fld_ty);
426  ofst_in_fld =
427  ((desired_offset - fld_offset)/TY_size(fld_ty)) * TY_size(fld_ty);
428  }
429 
430  if (TY_Is_Structured(fld_ty) &&
431  !Stab_Identical_Types(fld_ty, desired_ty,
432  FALSE, /* check_quals */
433  FALSE, /* check_scalars */
434  TRUE)) { /* ptrs_as_scalars */
435 #if DBGPATH
436  printf (" recurse \n");
437 #endif
438  FLD_PATH_INFO *fld_path2 =
439  TY2F_Get_Fld_Path(fld_ty, desired_ty,
440  desired_offset - (fld_offset+ofst_in_fld));
441 
442  /* If a matching path was found, attach "fld" to the path */
443  if (fld_path2 != NULL) {
444  if (TY_split(Ty_Table[fld_ty]))
445  fld_path = fld_path2; /* A stransparent substructure */
446  else {
447  fld_path = New_Fld_Path_Info(fld);
448  fld_path->arr_elt = is_array_elt;
449  fld_path->arr_ofst = ofst_in_fld;
450  fld_path->next = fld_path2;
451  }
452  } else {
453  fld_path = NULL;
454  }
455  } else { /* This may be a field we want to take into account */
456  const STAB_OFFSET fld_size = TY2F_Fld_Size(fld, max_fld_size);
457 
458  /* We only match a field with the expected size, offset
459  * and alignment.
460  */
461  if (desired_offset != fld_offset+ofst_in_fld || /* unexpected ofst */
462  // fld_size < (TY_size(fld_ty)+ofst_in_fld) || /* unexpected size */
463  TY_align(struct_ty) < TY_align(fld_ty)) { /* unexpected align */
464 #if DBGPATH
465  printf (" account - miss\n");
466 #endif
467 
468  fld_path = NULL;
469  } else { /* A match is found! */
470 #if DBGPATH
471  printf (" account - match\n");
472 #endif
473  fld_path = New_Fld_Path_Info(fld);
474  fld_path->arr_elt = is_array_elt;
475  fld_path->arr_ofst = ofst_in_fld;
476  }/*if*/
477  } /*if*/
478  } /*if*/
479 
480  return fld_path;
481  } /* Construct_Fld_Path */
482 
483 
484  static const char *
486  BOOL common_or_equivalence,
487  BOOL alt_return_name)
488  {
489  /* Since fields may be accessed in an unqualified manner in Fortran,
490  * e.g. for common block members and equivalences, so we need to treat
491  * them similar to the way we would treat regular objects.
492  */
493  const char *fld_name = NULL;
494 
495  if (common_or_equivalence && !alt_return_name) {
496  fld_name = FLD_name(fld);
497  } else {
498  fld_name = FLD_name(fld);
499  }
500  if (fld_name == NULL || *fld_name == '\0') { fld_name = "anon-fld"; }
501 
502  return fld_name;
503  } /* TY2F_Fld_Name */
504 
505 
506  /*------ Utilities for accessing and declaring KIND_STRUCTs ------
507  *----------------------------------------------------------------*/
508 
509  static void
511  const char *equiv_name,
512  const char *fld_name,
513  STAB_OFFSET fld_ofst)
514  {
515  /* Append one equivalence statement to the tokens buffer,
516  * keeping in mind that the equiv_name is based at index 1. */
517  xos << "EQUIVALENCE(" << equiv_name; /* equiv_name at given offset */
518  xos << "(" << Num2Str(fld_ofst, "%lld") << "),";
519  xos << fld_name << ")"; /* fld_name at offset zero */
520  } /* TY2F_Equivalence */
521 
522 
523  static void
525  FLD_HANDLE fldlist,
526  UINT equiv_var_idx,
527  mUINT64 ofst,
528  BOOL *common_block_equivalenced)
529  {
530  FLD_ITER fld_iter = Make_fld_iter(fldlist);
531 
532  do {
533  FLD_HANDLE fld (fld_iter);
534 
535  if (TY_split(Ty_Table[FLD_type(fld)]))
536  {
538  TY_flist(Ty_Table[FLD_type(fld)]),
539  equiv_var_idx,
540  ofst + FLD_ofst(fld),
541  common_block_equivalenced);
542  }
543  else if (FLD_equivalence(fld) || !*common_block_equivalenced)
544  {
545  xos << std::endl;
546  const char* tmpvar = StrCat("tmp", Num2Str(equiv_var_idx, "%d"));
547  TY2F_Equivalence(xos, tmpvar, TY2F_Fld_Name(fld_iter, TRUE/*equiv*/,
548  FALSE/*alt_ret*/),
549  ofst + FLD_ofst(fld));
550  if (!FLD_equivalence(fld))
551  *common_block_equivalenced = TRUE;
552  }
553 
554  }
555  while (!FLD_last_field (fld_iter++)) ;
556 
557  } /* TY2F_Equivalence_FldList */
558 
559 
560  static void
562  const TY_IDX struct_ty)
563  {
564  /* Append a nameless EQUIVALENCE specification statement for
565  * each equivalence field in the given struct. Declare a
566  * dummy symbol as an array of INTEGER*1 elements to represent
567  * the structure and each EQUIVALENCE specification will then
568  * equivalence a field to this dummy-symbol at the field offset.
569  *
570  * Group these declarations together by prepending each
571  * declaration (including the first one) with a newline.
572  *
573  * For COMMON blocks, it is also necessary to emit one element
574  * that is not an equivalence!
575  */
576  TY_IDX equiv_ty;
577  UINT equiv_var_idx;
578  BOOL common_block_equivalenced = FALSE;
579 
580  /* Declare an INTEGER*1 array (or CHARACTER string?) variable
581  * to represent the whole equivalenced structure. Don't unlock
582  * the tmpvar, or a similar equivalence group (ie: TY) will
583  * get the same temp.
584  */
585  equiv_ty = Stab_Array_Of(Stab_Mtype_To_Ty(MTYPE_I1), TY_size(struct_ty));
586  equiv_var_idx = Stab_Lock_Tmpvar(equiv_ty, &ST2F_Declare_Tempvar);
587 
588  /* Relate every equivalence field to the temporary variable.
589  */
591  TY_flist(Ty_Table[struct_ty]),
592  equiv_var_idx,
593  0, /* Initial offset */
594  &common_block_equivalenced);
595 
596  } /* TY2F_Equivalence_List */
597 
598  // static void
599  // TY2F_Translate_Structure(xml::ostream& xos, TY_IDX ty)
600  // {
601  // FORTTK_ASSERT(TY_kind(ty) == KIND_STRUCT, "Unexpected type " << TY_kind(ty));
602 
603  // FLD_ITER fld_iter;
604  // TY& ty_rt = Ty_Table[ty];
605 
606  // PUXlationContext ctxt;// FIXME
607 
608  // xos << std::endl;
609 
610  // /* Emit structure header */
611  // xos << "TYPE " << TY_name(ty);
612 
613  // if (TY_is_sequence(ty_rt)) {
614  // xos << std::endl << "SEQUENCE ";
615  // }
616 
617  // /* Emit structure body */
618  // FLD_IDX flist = ty_rt.Fld();
619 
620  // if (flist != 0) {
621  // fld_iter = Make_fld_iter(TY_flist(ty_rt));
622  // do {
623  // FLD_HANDLE fld (fld_iter);
624 
625  // /* if it's a bitfield, then assume it's part of a dope vector & */
626  // /* just put out the name of the first bitfield in this I4 */
627  // if (NOT_BITFIELD_OR_IS_FIRST_OF_BITFIELD(fld_iter)) {
628  // /* See if this field starts a map or a union */
629 
630  // xos << std::endl;
631  // if (FLD_begin_union(fld)) {
632  // xos << " UNION" << std::endl;
633  // } else if (FLD_begin_map(fld)) {
634  // xos << " MAP" << std::endl;
635  // }
636 
637  // /* Declare this field */
638  // if (FLD_is_pointer(fld)) {
639  // xos << ",POINTER::";
640  // }
641 
642  // xos << TY2F_Fld_Name(fld_iter, FALSE/*common*/, FALSE/*alt_ret_name*/);
643 
644  // if (FLD_is_pointer(fld) && (TY_kind(FLD_type(fld)) == KIND_ARRAY)) {
645  // TY2F_array_for_pointer(xos, FLD_type(fld), ctxt);
646  // } else {
647  // TY2F_translate(xos, FLD_type(fld), ctxt);
648  // }
649 
650  // /* See if this field terminates a map or union */
651  // if (FLD_end_union(fld)) {
652  // xos << std::endl << "END UNION";
653  // } else if (FLD_end_map(fld)) {
654  // xos << std::endl << "END MAP";
655  // }
656  // }
657  // } while (!FLD_last_field (fld_iter++)) ;
658  // }
659 
660  // /* Emit structure tail */
661  // xos << std::endl;
662  // xos << "END TYPE" << std::endl;
663  // }
664 
665 
666  static void
668  {
669  assert(0);
670  }
671 
672  static void
674  FLD_HANDLE fldlist,
675  BOOL alt_return, /* Alternate return points */
676  BOOL *is_equiv) /* out */
677  {
678  assert(0);
679  }
680 
681  static void
683  {
684  FLD_ITER fld_iter = Make_fld_iter(fldlist);
685 
686  do {
687  FLD_HANDLE fld (fld_iter);
688  TY & ty = Ty_Table[FLD_type(fld)];
689 
690  if (TY_split(ty)) {
691  /* Treat a full split element as a transparent data-structure */
693  } else if (!FLD_equivalence(fld)) {
694  xos << TY2F_Fld_Name(fld_iter, TRUE/*common*/, FALSE/*alt_ret_name*/);
695  }
696 
697  if (!FLD_last_field(fld)) {
698  FLD_ITER next_iter = fld_iter ;
699  FLD_HANDLE next (++next_iter);
700  if (!FLD_equivalence(next))
701  xos << ',';
702  }
703 
704  } while (!FLD_last_field (fld_iter++)) ;
705 
706  } /* TY2F_List_Common_Flds */
707 
708  /*------------- Hidden routines to declare variable types -------------*/
709  /*---------------------------------------------------------------------*/
710 
711  static void
713  {
715  }
716 
717  static void
719  {
721 
722  TY& ty = Ty_Table[ty_idx];
723  MTYPE mt = TY_mtype(ty);
724 
725  const char* type_str;
726  if (TY_is_character(ty)) {
727  type_str = "CHARACTER";
728  } else if (TY_is_logical(ty)) {
729  type_str = "LOGICAL";
730  } else {
731  switch(mt) {
732  case MTYPE_U1: // Strictly speaking unsigned integers not supported
733  case MTYPE_U2: // in Fortran, but we are lenient and treat them
734  case MTYPE_U4: // as the signed equivalent.
735  case MTYPE_U8:
736 
737  case MTYPE_I1:
738  case MTYPE_I2:
739  case MTYPE_I4:
740  case MTYPE_I8:
741  type_str = "INTEGER";
742  break;
743 
744  case MTYPE_F4:
745  case MTYPE_F8:
746  case MTYPE_FQ:
747  type_str = "REAL";
748  break;
749 
750  case MTYPE_C4:
751  case MTYPE_C8:
752  case MTYPE_CQ:
753  type_str = "COMPLEX";
754  break;
755 
756  case MTYPE_M:
757  type_str = "memory block";
758  break;
759 
760  default:
761  FORTTK_DIE("Unexpected type " << MTYPE_name(mt));
762  }
763  }
764 
765  const char* size_str;
766  INT64 size;
767  if (TY_size(ty) > 0) {
768  if (ctxt.isF90() && MTYPE_is_complex(mt)) {
769  size = TY_size(ty) / 2;
770  } else {
771  size = TY_size(ty);
772  }
773  size_str = Num2Str(size, "%lld");
774  } else {
775  if (mt == MTYPE_M) {
776  size_str = ".mblock.";
777  } else {
779  "Unexpected type size " << TY_size(ty));
780  size_str = "*";
781  }
782  }
783 
784  const char* str = StrCat(type_str, size_str);
785 
786  xos << xml::BegElem("xaif:Property") << xml::Attr("id", ctxt.currentXlationContext().getNewVertexId())
787  << xml::Attr("name", "type") << xml::Attr("value", str) << xml::EndElem;
788 
789  xos << xml::BegElem("xaif:Property") << xml::Attr("id", ctxt.currentXlationContext().getNewVertexId())
790  << xml::Attr("name", "whirltype") << xml::Attr("value", TY_name(ty)) << xml::EndElem;
791  }
792 
793  static void
795  {
796  TY& ty = Ty_Table[ty_idx];
797 
799 
800  xos << xml::BegElem("xaif:Property") << xml::Attr("id", ctxt.currentXlationContext().getNewVertexId())
801  << xml::Attr("name", "whirlkind") << xml::Attr("value", "array") << xml::EndElem;
802 
803 
804  if (TY_is_character(ty)) { // FIXME
805  // A character string...
806  if (TY_size(ty) > 0) /* ... of known size */
807  xos << "CHARACTER*" << Num2Str(TY_size(ty), "%lld");
808  else /* ... of unknown size */
809  xos << "CHARACTER*(*)";
810 
811  } else {
812  // A regular array, so prepend the element type and append
813  // the index bounds.
814  ARB_HANDLE arb_base = TY_arb(ty);
815  INT32 dim = ARB_dimension(arb_base) ;
816  INT32 co_dim = ARB_co_dimension(arb_base);
817  INT32 array_dim = dim - co_dim;
818  INT32 revdim = 0;
819 
820  if (ARB_co_dimension(arb_base) <= 0) {
821  co_dim = 0;
822  array_dim = dim;
823  }
824 
825  // 1. Translate element type
826  xos << xml::BegElem("xaif:Property") << xml::Attr("id", ctxt.currentXlationContext().getNewVertexId())
827  << xml::Attr("name", "ArrayElementType");
828 
829  // Do not permit pointers as elements of arrays, so just use
830  // the corresponding integral type instead. We do not expect
831  // such pointers to be dereferenced anywhere. (FIXME)
832  if (TY_Is_Pointer(TY_AR_etype(ty)))
834  else
835  TY2F_translate(xos, TY_AR_etype(ty), ctxt);
836 
837  xos << xml::EndElem;
838 
839  // 2. Translate dimension attributes
840  while (array_dim > 0) {
841 
842  xos << xml::BegElem("xaif:Property") << xml::Attr("id", ctxt.currentXlationContext().getNewVertexId())
843  << xml::Attr("name", "ArrayDimensionAttr") << xml::Attr("dim", dim);
844 
845  ARB_HANDLE arb = arb_base[dim-1];
846  TY2F_Append_ARB(xos, arb, ty_idx, ctxt);
847 
848  xos << xml::EndElem;
849 
850  array_dim--;
851  dim--;
852  revdim++;
853  }
854 
855  // 3. What is this???
856  dim = ARB_dimension(arb_base);
857  array_dim = dim - co_dim;
858  --dim;
859 
860  if (co_dim > 0) {
861  xos << '[';
862  while (co_dim > 0) {
863  ARB_HANDLE arb = arb_base[dim-array_dim];
864 
865 
866  if (TY_is_f90_deferred_shape(ty))
867  TY2F_Append_ARB(xos, arb, ty_idx, ctxt);
868  else {
869  if (co_dim == 1)
870  TY2F_Append_ARB(xos, arb, ty_idx, ctxt); // TRUE
871  else
872  TY2F_Append_ARB(xos, arb, ty_idx, ctxt); // FALSE
873  }
874 
875  dim--;
876 
877  if (co_dim > 1)
878  xos << ',';
879 
880  co_dim--;
881  ++revdim;
882  }
883  xos << ']';
884  }
885 
886  }
887  } /* TY2F_array */
888 
889 
890  static void
892  {
893  TY& ty = Ty_Table[ty_idx] ;
894 
896 
897  if (TY_is_character(ty)) {
898  /* A character string...
899  */
900  if (TY_size(ty) > 0) /* ... of known size */
901  xos << "CHARACTER*" << Num2Str(TY_size(ty), "%lld");
902  else /* ... of unknown size */
903  xos << "CHARACTER*(*)";
904  } else {
905  /* A regular array, so prepend the element type and append
906  * the index bounds.
907  */
908  ARB_HANDLE arb_base = TY_arb(ty);
909  INT32 dim = ARB_dimension(arb_base) ;
910  INT32 co_dim = ARB_co_dimension(arb_base);
911  INT32 array_dim = dim-co_dim;
912  INT32 revdim = 0;
913 
914  /* Do not permit pointers as elements of arrays, so just use
915  * the corresponding integral type instead. We do not expect
916  * such pointers to be dereferenced anywhere.
917  */
918  if (TY_Is_Pointer(TY_AR_etype(ty)))
920  else
921  TY2F_translate(xos, TY_AR_etype(ty), ctxt);
922 
923  if (ARB_co_dimension(arb_base)<=0) {
924  co_dim=0;
925  array_dim = dim;
926  }
927 
928  if (array_dim>0) {
929  xos << "(";
930 
931  while (array_dim > 0) {
932  ARB_HANDLE arb = arb_base[dim-1];
933  xos << ':';
934  if (array_dim-- > 1)
935  xos << ',';
936 
937  --dim;
938  ++revdim;
939  }
940 
941  xos << ')';
942  }
943 
944  dim = ARB_dimension(arb_base);
945  array_dim = dim - co_dim;
946  --dim;
947 
948  if (co_dim > 0) {
949  xos << '[';
950  while (co_dim > 0) {
951  ARB_HANDLE arb = arb_base[dim-array_dim];
952  xos << ':';
953  dim--;
954 
955  if (co_dim-- > 1)
956  xos << ',';
957 
958  ++revdim;
959  }
960  xos << ']';
961  }
962  }
963  } /* TY2F_array_for_pointer */
964 
965 
966  static void
968  {
969  /* Structs are supported by VAX-Fortran and Fortran-90. Note
970  * that we here emit a RECORD declaration, while we expect
971  * the STRUCTURE to have been declared through a call to
972  * TY2F_Translate_Structure().
973  */
974  TY& ty_rt = Ty_Table[ty];
976 
977  xos << "(" << TY_name(ty) << ")" << "TYPE";
978 
979 #if 0 // see Open64 stab_attr.cxx; if needed simulate thru PUXlationContext
980  if (!TY_is_translated_to_c(ty)) {
981  TY2F_Translate_Structure(xos, ty);
982  Set_TY_is_translated_to_c(ty); /* Really, translated to Fortran, not C */
983  }
984 #endif
985  }
986 
987 
988  static void
990  {
991  /* Structs are supported by VAX-Fortran and Fortran-90. Note
992  * that we here emit a RECORD declaration, while we expect
993  * the STRUCTURE to have been declared through a call to
994  * TY2F_Translate_Structure().
995  */
996  TY & ty_rt = Ty_Table[ty];
998 
999 #if 0 // see Open64 stab_attr.cxx; if needed simulate thru PUXlationContext
1000  if (!TY_is_translated_to_c(ty)) {
1001  TY2F_Translate_Structure(xos, ty);
1002  Set_TY_is_translated_to_c(ty); /* Really, translated to Fortran, not C */
1003  }
1004 #endif
1005  }
1006 
1007 
1008  static void
1010  {
1011  /* Is a dope vector base address? Put out an integer large enough */
1012  /* to hold an address for now. Don't really want POINTER because */
1013  /* implies cray/f90 pointer instead of address slot */
1014 
1015  if (TY2F_Pointer_To_Dope(ty)) {
1016 #if 0
1017  Prepend_Token_String(xos,",POINTER ::");
1018 #endif
1020  } else {
1021  /* avoid recursive type declarations */
1022  if (TY_kind(TY_pointed(ty)) == KIND_STRUCT) {
1023 #if 0
1024  Prepend_Token_String(xos,",POINTER ::");
1025  Prepend_Token_String(xos, TY_name(TY_pointed(ty)));
1026 #endif
1028 
1029  } else
1030  TY2F_translate(xos,TY_pointed(ty), ctxt);
1031  }
1032  } /* TY2F_pointer */
1033 
1034  static void
1036  {
1037  TY& ty = Ty_Table[ty_idx];
1039  xos << std::endl << "! <Void Type>";
1040  }
1041 
1042  /*------------------------ exported routines --------------------------*/
1043  /*---------------------------------------------------------------------*/
1044 
1045 
1046  // JU: I don't think the conditions under which this method is called
1047  // in the rest of the code are ever satisfied.
1048  void
1050  TY_IDX arr_ty_idx,
1051  STAB_OFFSET arr_ofst)
1052  {
1053  std::cout << "TEMP WARNING" << std::endl;
1054  }
1055 
1056 
1057  void
1058  TY2F_Translate_Common(xml::ostream& xos, const char *name, TY_IDX ty_idx)
1059  {
1060  TY& ty = Ty_Table[ty_idx];
1061  BOOL is_equiv = FALSE;
1062 
1065 
1066  // Emit specification statements for every element of the common
1067  // block, including equivalences.
1068  xos << xml::BegComment << "COMMON";
1069  if (name != NULL && *name != '\0') { xos << " name = " << name; }
1070  xos << xml::EndComment;
1071 
1072 #if 0 // FIXME
1073  TY2F_List_Common_Flds(xos, TY_flist(ty));
1074 
1075  // variables in common block type declaration
1076  TY2F_Declare_Common_Flds(xos, TY_flist(ty), FALSE /*alt_return*/, &is_equiv);
1077 
1078  // Emit equivalences, if there are any
1079  if (is_equiv)
1080  TY2F_Equivalence_List(xos, ty_idx /*struct_ty*/);
1081 #endif
1082  }
1083 
1084 
1085  void
1087  {
1088  /* When alt_return==TRUE, this represents an alternate return variable,
1089  * in which case we should declare the elements of the equivalence
1090  * with unmangled names and ignore the fact that they are in an
1091  * equivalence. The first element in such an alternate return is
1092  * the function/subprogram return-variable, which we should never
1093  * declare.
1094  */
1095  TY& ty = Ty_Table[ty_idx];
1096 
1097  FLD_HANDLE first_fld;
1098  BOOL is_equiv;
1099 
1102 
1103  if (alt_return) {
1104  first_fld = FLD_next(TY_flist(ty)); /* skip func_entry return var */
1105  } else {
1106  first_fld = TY_flist(ty);
1107  }
1108 
1109  /* Emit specification statements for every element of the
1110  * equivalence block.
1111  */
1112  TY2F_Declare_Common_Flds(xos, first_fld, alt_return,
1113  &is_equiv); /* Redundant in this call */
1114 
1115  if (!alt_return)
1116  TY2F_Equivalence_List(xos, ty_idx /*struct_ty*/);
1117 
1118  } /* TY2F_Translate_Equivalence */
1119 
1120 
1121  FLD_PATH_INFO *
1123  {
1124  FLD_PATH_INFO *free_list;
1125 
1126  if (fld_path != NULL) {
1127  free_list = Free_Fld_Path_Info;
1128  Free_Fld_Path_Info = fld_path;
1129  while (fld_path->next != NULL)
1130  fld_path = fld_path->next;
1131  fld_path->next = free_list;
1132  }
1133  return NULL;
1134  } /* TY2F_Free_Fld_Path */
1135 
1136 
1137  FLD_PATH_INFO *
1138  TY2F_Get_Fld_Path(const TY_IDX struct_ty, const TY_IDX object_ty,
1139  STAB_OFFSET offset)
1140  {
1141  FLD_PATH_INFO* fld_path;
1142  FLD_PATH_INFO* fld_path2 = NULL;
1143  TY& s_ty = Ty_Table[struct_ty];
1144  FLD_ITER fld_iter;
1145 
1146  FORTTK_ASSERT(TY_kind(s_ty) == KIND_STRUCT,
1148 
1149  /* Get the best matching field path into fld_path2 */
1150  fld_iter = Make_fld_iter(TY_flist(s_ty));
1151 
1152  do {
1153  FLD_HANDLE fld (fld_iter);
1154 
1155  if (NOT_BITFIELD_OR_IS_FIRST_OF_BITFIELD(fld_iter)) {
1156  fld_path = Construct_Fld_Path(fld_iter, struct_ty, object_ty,
1157  offset, TY_size(s_ty));
1158  if (fld_path2 == NULL)
1159  fld_path2 = fld_path;
1160  else if (fld_path != NULL)
1161  fld_path2 = Select_Best_Fld_Path(fld_path2, fld_path, object_ty,
1162  offset);
1163  }
1164  } while (!FLD_last_field (fld_iter++));
1165 
1166  /* POSTCONDITION: fld_path2 points to the best match found */
1167  return fld_path2;
1168  }
1169 
1170  void
1172  FLD_PATH_INFO *fld_path,
1173  BOOL deref,
1174  BOOL member_of_common,
1175  BOOL alt_ret_name,
1176  PUXlationContext& ctxt)
1177  {
1178  /* Append the name of each field to the tokens, separated them
1179  * from each other by the field-selection operator ('.'). The
1180  * first name on the path may optionally be emitted in unclobbered
1181  * form, as it may represent an alternate return point.
1182  */
1183  while (fld_path != NULL) {
1184  FLD_HANDLE f (fld_path->fld);
1185  const char* str = TY2F_Fld_Name(f, member_of_common, alt_ret_name);
1186  if (deref && TY_Is_Pointer(FLD_type(f))) {
1187  str = StrCat("deref_", str); // W2CF_Symtab_Nameof_Fld_Pointee(f);
1188  }
1189  xos << xml::BegElem("TYFLD") << xml::Attr("***name", str) << xml::EndElem;
1190 
1191  member_of_common = FALSE; /* Can only be true first time around */
1192 
1193  /* if an array element, form the subscript list. If an OPC_ARRAY */
1194  /* provides the subscripts, use it o/w use offset */
1195  if (fld_path->arr_elt) {
1196  if (fld_path->arr_wn != NULL)
1197  WN2F_array_bounds(xos, fld_path->arr_wn, FLD_type(f), ctxt);
1198  }
1199 
1200  /* Separate fields with the dot-notation. */
1201  fld_path = fld_path->next;
1202  if (fld_path != NULL) {
1203  TY2F_Fld_Separator(xos) ;
1204  alt_ret_name = FALSE; /* Only applies to first field on the path */
1205  }
1206  } /* while */
1207 
1208  } /* TY2F_Translate_Fld_Path */
1209 
1210 
1211  extern void
1213  {
1214  /* puts out the appropriate structure component separator*/
1215  xos << '%';
1216  }
1217 
1218  extern FLD_HANDLE
1220  {
1221  FLD_HANDLE f = FLD_HANDLE () ;
1222 
1223  while (fld_path != NULL) {
1224  f = fld_path->fld;
1225  fld_path = fld_path->next ;
1226  }
1227 
1228  return f;
1229  }
1230 
1231  extern FLD_PATH_INFO *
1233  {
1234  /* given a fld path, return a pointer to */
1235  /* the slot at the given offset */
1236  while (path != NULL) {
1237  if ((INT64)FLD_ofst(path->fld) >= off)
1238  break ;
1239  path=path->next;
1240  }
1241  return path;
1242  }
1243 
1244  extern void
1246  {
1247  printf ("path ::");
1248  while (fld_path != NULL) {
1249  FLD_HANDLE f = fld_path->fld;
1250 
1251  printf ("%s(#%d)",TY2F_Fld_Name(f,FALSE,FALSE),f.Idx ());
1252 
1253  if (fld_path->arr_elt)
1254  printf (" array");
1255 
1256  if (fld_path->arr_ofst)
1257  printf (" offset 0x%x",(mINT32) fld_path->arr_ofst);
1258 
1259  if (fld_path->arr_wn != NULL)
1260  printf (" tree 0x%p",fld_path->arr_wn);
1261 
1262  printf (" ::");
1263  fld_path = fld_path->next ;
1264  }
1265  printf ("\n");
1266  }
1267 
1268 
1269  // ***************************************************************************
1270  //
1271  // ***************************************************************************
1272 
1273 
1274  const char*
1276  {
1277  TY& ty = Ty_Table[ty_idx];
1278  const char* str = NULL;
1279 
1280  if (TY_kind(ty) == KIND_SCALAR) {
1281  MTYPE mt = TY_mtype(ty);
1282  if (TY_is_character(ty)) {
1283  str = "char";
1284  }
1285  else if (TY_is_logical(ty)) {
1286  str = "bool";
1287  }
1288  else if (MTYPE_is_integral(mt)) {
1289  str = "integer";
1290  }
1291  else if (MTYPE_is_complex(mt)) { /* must come before 'float' */
1292  str = "complex";
1293  }
1294  else if (MTYPE_is_float(mt)) {
1295  str = "real";
1296  }
1297  }
1298  else if (TY_kind(ty) == KIND_ARRAY) {
1299  if (TY_is_character(ty)) {
1300  str = "string";
1301  }
1302  else {
1303  // Do not permit pointers as elements of arrays, so just use
1304  // the corresponding integral type instead. We do not expect
1305  // such pointers to be dereferenced anywhere. (FIXME)
1306  TY_IDX ety_idx = TY_AR_etype(ty);
1307  if (TY_Is_Pointer(ety_idx)) {
1308  ety_idx = Stab_Mtype_To_Ty(TY_mtype(ety_idx));
1309  }
1310  str = TranslateTYToSymType(ety_idx);
1311  }
1312  }
1313  else if (TY_kind(ty) == KIND_STRUCT
1314  ||
1315  TY_kind(ty) == KIND_INVALID) {
1316  // the latter applies to symbols that are f90 interface names
1317  str = "opaque";
1318  }
1319  else if (TY_kind(ty) == KIND_FUNCTION) {
1320  str = "void";
1321  }
1322  else if (TY_kind(ty) == KIND_POINTER) {
1323  str = "opaque";
1324  if (TY_kind(TY_pointed(ty)) == KIND_FUNCTION) {
1325  str = "void";
1326  }
1327  }
1328  else
1329  FORTTK_DIE("whirl2xaif::TranslateTYToSymType: no logic to handle type of kind " << TY_kind(ty));
1330  return str;
1331  }
1332 
1333  const char*
1335  TY& ty_r = Ty_Table[ty_idx];
1336  if (TY_kind(ty_r) == KIND_SCALAR) {
1337  return Mtype_Name(TY_mtype(ty_r));
1338  }
1339  else if (TY_kind(ty_r) == KIND_ARRAY) {
1340  if (TY_is_character(ty_r)) {
1341  return Mtype_Name(TY_mtype(ty_r));
1342  }
1343  else {
1344  // Do not permit pointers as elements of arrays, so just use
1345  // the corresponding integral type instead. We do not expect
1346  // such pointers to be dereferenced anywhere. (FIXME)
1347  TY_IDX ety_idx = TY_AR_etype(ty_r);
1348  if (TY_Is_Pointer(ety_idx)) {
1349  ety_idx = Stab_Mtype_To_Ty(TY_mtype(ety_idx));
1350  }
1351  return TranslateTYToMType(ety_idx);
1352  }
1353  }
1354  else if (TY_kind(ty_r) == KIND_STRUCT
1355  ||
1356  TY_kind(ty_r) == KIND_INVALID
1357  ||
1358  TY_kind(ty_r) == KIND_FUNCTION) {
1359  return Mtype_Name(TY_mtype(ty_r));
1360  }
1361  else if (TY_kind(ty_r) == KIND_POINTER) {
1362  return TranslateTYToMType(TY_pointed(ty_r));
1363  }
1364  else
1365  FORTTK_DIE("whirl2xaif::TranslateTYToMType: no logic to handle type of kind " << TY_kind(ty_r));
1366  return "";
1367  }
1368 
1369  const char*
1371  {
1372  TY& ty = Ty_Table[ty_idx];
1373  const char* str = NULL;
1374 
1375  if (TY_kind(ty) == KIND_SCALAR) {
1376  str = "scalar";
1377  }
1378  else if (TY_kind(ty) == KIND_ARRAY) {
1379 
1380  ARB_HANDLE arb_base = TY_arb(ty);
1381  INT32 dim = ARB_dimension(arb_base);
1382  // ARB_co_dimension(arb_base) <= 0 FIXME
1383 
1384  if (TY_is_character(ty)) {
1385  str = "scalar";
1386  }
1387  else {
1388  switch (dim) {
1389  case 1: str = "vector"; break;
1390  case 2: str = "matrix"; break;
1391  case 3: str = "three_tensor"; break;
1392  case 4: str = "four_tensor"; break;
1393  case 5: str = "five_tensor"; break;
1394  case 6: str = "six_tensor"; break;
1395  case 7: str = "seven_tensor"; break;
1396  default:
1397  FORTTK_DIE("Invalid array dimension: " << dim);
1398  }
1399  }
1400 
1401  }
1402  else if (TY_kind(ty) == KIND_STRUCT
1403  ||
1404  TY_kind(ty) == KIND_INVALID) {
1405  // the latter applies to symbols that are f90 interface names
1406  str = "scalar"; // FIXME
1407  }
1408  else if ((TY_kind(ty) == KIND_POINTER) &&
1409  (TY_kind(TY_pointed(ty)) == KIND_FUNCTION)) {
1410  str = "void";
1411  }
1412 
1413  return str;
1414  }
1415 
1416 }