PIPS
declarations.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "linear.h"
#include "genC.h"
#include "misc.h"
#include "properties.h"
#include "ri-util.h"
#include "text-util.h"
#include "prettyprint.h"
+ Include dependency graph for declarations.c:

Go to the source code of this file.

Functions

text c_text_entity (entity module, entity e, int margin, list *ppdl, bool init_p)
 Regeneration of declarations from the symbol table. More...
 
list c_words_entity (type t, list name, list *ppdl)
 
static list words_initial_qualifiers (list obj)
 
list words_dimensions (list dims, list *ppdl)
 
static list words_constant (constant obj)
 
static list words_value (value obj)
 
static list words_parameters (entity e, list *ppdl)
 
static list words_dimension (dimension obj, list *ppdl)
 
list words_declaration (entity e, bool prettyprint_common_variable_dimensions_p, list *ppdl)
 some compilers don't like dimensions that are declared twice. More...
 
list words_basic (basic obj, list *ppdl)
 what about simple DOUBLE PRECISION, REAL, INTEGER... More...
 
sentence sentence_variable (entity e, list *ppdl)
 
sentence Sentence_Variable (entity e)
 
sentence sentence_head (entity e, list *ppdl)
 We have no way to distinguish between the SUBROUTINE and PROGRAM They two have almost the same properties. More...
 
static list generic_words_qualifiers (list obj, bool initial_p, bool late_p)
 ================C prettyprinter functions================= More...
 
list words_qualifiers (list obj)
 
static list words_late_qualifiers (list obj)
 
list words_type (type obj, list *ppdl, bool argument_p)
 obj is the type to describe More...
 
list Words_Type (type obj)
 
bool c_brace_expression_p (expression e)
 
list words_brace_expression (expression exp, list *ppdl)
 
list generic_c_words_entity (type t, list name, bool is_safe, bool add_dummy_parameter_name_p, list *ppdl)
 This recursive function prints a C variable with its type. More...
 
list generic_c_words_simplified_entity (type t, list name, bool is_safe, bool add_dummy_parameter_name_p, bool is_first, bool in_type_declaration, bool argument_p, list *ppdl)
 Same as above, but the bool is_first is used to skip a type specifier which is useful when several variables or types are defined in a unique statement such as "int i, *pi, ai[10],...;". More...
 
list c_words_simplified_entity (type t, list name, bool is_first, bool in_type_declaration, list *ppdl)
 The declaration list pointer ppdl is passed down to determine if an internal derived type must be fully expanded within another declaration or not. More...
 
list safe_c_words_entity (type t, list name)
 
text c_text_entities (entity module, list ldecl, int margin, list *ppdl)
 Generate declarations for a list of entities belonging to the same statement declaration. More...
 
static list words_struct_reference (const char *name1, list pc, bool init_p)
 To print out a struct reference, such as "struct s". More...
 
static list words_enum_reference (const char *name1, list pc, bool init_p)
 Prolog to print out a struct definition, such as "struct s { int a; int b;}"; for the time being, only the previous function is used. More...
 
static list words_enum (const char *name1, list l, bool space_p, list pc, list *ppdl)
 
static list words_union (const char *name1, list pc, bool init_p)
 
static list words_variable_or_function (entity module, entity e, bool is_first, list pc, bool in_type_declaration, list *ppdl, bool init_p)
 
static list filtered_declaration_list (list del, list *pcl)
 Fix the declaration list produced by the parser, which includes declared program variables but also derived types used in the declaration or the initialization, to accomodate the prettyprinter, which must decide which derived types appearing in the declaration must be defined, and which one must be referenced: More...
 
text c_text_related_entities (entity module, list del, int margin, int sn, list *ppdl, list cl)
 It is assumed that all entities in list el can be declared by an unique statement, i.e. More...
 
text c_text_entity_simple (entity module, entity e, int margin)
 

Function Documentation

◆ c_brace_expression_p()

bool c_brace_expression_p ( expression  e)

Definition at line 898 of file declarations.c.

899 {
900  if (expression_call_p(e))
901  {
904  return true;
905  }
906  return false;
907 }
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
#define ENTITY_BRACE_INTRINSIC_P(e)
C initialization expression.
bool expression_call_p(expression e)
Definition: expression.c:415
#define call_function(x)
Definition: ri.h:709
#define syntax_call(x)
Definition: ri.h:2736
#define expression_syntax(x)
Definition: ri.h:1247

References call_function, ENTITY_BRACE_INTRINSIC_P, expression_call_p(), expression_syntax, f(), and syntax_call.

Referenced by words_brace_expression().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ c_text_entities()

text c_text_entities ( entity  module,
list  ldecl,
int  margin,
list ppdl 
)

Generate declarations for a list of entities belonging to the same statement declaration.

ppdl: derived from the parser declared entity; used to decide if a derived type entity de must be declared as a reference to de (e.g. "struct s") or as the type definition of de (e.g. "struct s {}"). Of course, the type can be defined only once, even if it is referenced several times. Hence, pdl, the list pointed to by ppdl is updated in the loop to avoid redeclarations.

Dummy enum must be printed sometimes because their members are exposed directly.

Parameters
moduleodule
ldecldecl
marginargin
ppdlpdl

Definition at line 1452 of file declarations.c.

1453 {
1454  text r = make_text(NIL);
1455  //list npdl = gen_copy_seq(pdl); // new parser declaration list
1456 
1457  FOREACH(ENTITY, e, ldecl) {
1458  text tmp = text_undefined;
1459  type t = entity_type(e);
1460 
1461  if(!type_area_p(t)
1462  && ! type_statement_p(t)
1463  && !type_unknown_p(t)
1465  && !implicit_c_variable_p(e)) {
1466  string n = entity_name(e);
1467 
1468  /* Dummy enum must be printed sometimes because their members
1469  are exposed directly. */
1470  if(((strstr(n,DUMMY_ENUM_PREFIX)==NULL)
1471  || !type_used_in_type_declarations_p(e, ldecl))
1472  && (strstr(n,STRUCT_PREFIX DUMMY_STRUCT_PREFIX)==NULL
1473  ||strstr(n,MEMBER_SEP_STRING)!=NULL)
1474  && (strstr(n,UNION_PREFIX DUMMY_UNION_PREFIX)==NULL
1475  ||strstr(n,MEMBER_SEP_STRING)!=NULL) ) {
1476  type et = ultimate_type(entity_type(e));
1477  bool init_p = true; // So as not to modify the behavior although no initializations are expected here
1478  // FI: I do not understand the copies of pdl in npdl
1479  tmp = c_text_entity(module, e, margin, ppdl, init_p);
1480  MERGE_TEXTS(r,tmp);
1481 
1482  if(derived_type_p(et)) {
1484  //gen_remove(&npdl, (void *) de);
1485  *ppdl = gen_once((void *) de, *ppdl);
1486  }
1487  }
1488  }
1489  }
1490 
1491  //gen_free_list(npdl);
1492 
1493  return r;
1494 }
text make_text(list a)
Definition: text.c:107
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
list gen_once(const void *vo, list l)
Prepend an item to a list only if it is not already in the list.
Definition: list.c:722
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define DUMMY_STRUCT_PREFIX
Definition: naming-local.h:87
#define DUMMY_ENUM_PREFIX
For enum and struct and union without names (see c_syntax/cyacc.y)
Definition: naming-local.h:86
#define UNION_PREFIX
Definition: naming-local.h:58
#define DUMMY_UNION_PREFIX
Definition: naming-local.h:88
#define MEMBER_SEP_STRING
Definition: naming-local.h:53
#define STRUCT_PREFIX
Definition: naming-local.h:56
static char * module
Definition: pips.c:74
text c_text_entity(entity module, entity e, int margin, list *ppdl, bool init_p)
Regeneration of declarations from the symbol table.
bool type_used_in_type_declarations_p(entity e, list ldecl)
check if e is used to declare one of the entities in entity list ldecl
Definition: entity.c:2289
type ultimate_type(type)
Definition: type.c:3466
bool derived_type_p(type)
Returns true if t is of type struct, union or enum.
Definition: type.c:3104
bool implicit_c_variable_p(entity)
Definition: variable.c:1877
#define storage_formal_p(x)
Definition: ri.h:2522
#define type_unknown_p(x)
Definition: ri.h:2956
#define basic_derived(x)
Definition: ri.h:640
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define type_variable(x)
Definition: ri.h:2949
#define entity_storage(x)
Definition: ri.h:2794
#define type_statement_p(x)
Definition: ri.h:2941
#define entity_name(x)
Definition: ri.h:2790
#define type_area_p(x)
Definition: ri.h:2944
#define entity_type(x)
Definition: ri.h:2792
#define variable_basic(x)
Definition: ri.h:3120
#define MERGE_TEXTS(r, t)
#define text_undefined
Definition: text.h:91

References basic_derived, c_text_entity(), derived_type_p(), DUMMY_ENUM_PREFIX, DUMMY_STRUCT_PREFIX, DUMMY_UNION_PREFIX, ENTITY, entity_name, entity_storage, entity_type, FOREACH, gen_once(), implicit_c_variable_p(), make_text(), MEMBER_SEP_STRING, MERGE_TEXTS, module, NIL, storage_formal_p, STRUCT_PREFIX, text_undefined, type_area_p, type_statement_p, type_unknown_p, type_used_in_type_declarations_p(), type_variable, ultimate_type(), UNION_PREFIX, and variable_basic.

Referenced by c_text_related_entities(), and ensure_comment_consistency().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ c_text_entity()

text c_text_entity ( entity  module,
entity  e,
int  margin,
list ppdl,
bool  init_p 
)

Regeneration of declarations from the symbol table.

FI: strange recursion, probably due to Francois...

Regeneration of declarations... ==================== Variables and Function prototypes for C =========== pdl is the parser declaration list. It is used to decide if a derived entity should be simply declared, "struct s", or fully defined, "struct s {....}". It is accessed by its pointer ppdl

c_text_related_entities calls c_text_entities calls c_text_entity calls back c_text_related_entities (!) but with only one element... may call words_variable_or_function calls c_words_simplified_entity calls generic_c_words_simplified_entity

Note: text when newline are involved, words when everything fits on one line.

Parameters
moduleodule
marginargin
ppdlpdl
init_pnit_p

Definition at line 2087 of file declarations.c.

2088 {
2089  list el = CONS(ENTITY, e, NIL);
2090  list il = CONS(EXPRESSION, int_to_expression(init_p? 1 : 0), NIL);
2091  // No implicit "extern" keyword
2092  il = CONS(EXPRESSION, int_to_expression(0), NIL);
2093  text t = c_text_related_entities(module, el, margin, 0, ppdl, il);
2094  gen_free_list(el);
2095  gen_full_free_list(il);
2096 
2097  return t;
2098 }
void gen_full_free_list(list l)
Definition: genClib.c:1023
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
text c_text_related_entities(entity module, list del, int margin, int sn, list *ppdl, list cl)
It is assumed that all entities in list el can be declared by an unique statement,...
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References c_text_related_entities(), CONS, ENTITY, EXPRESSION, gen_free_list(), gen_full_free_list(), int_to_expression(), module, and NIL.

Referenced by c_text_entities(), c_text_entity_simple(), and compilation_unit_text().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ c_text_entity_simple()

text c_text_entity_simple ( entity  module,
entity  e,
int  margin 
)
Parameters
moduleodule
marginargin

Definition at line 2100 of file declarations.c.

2101 {
2102  list pdl = NIL; // pdl is useless in Fortran or in some debugging situations
2103  bool init_p = true;
2104  text t = c_text_entity(module, e, margin, &pdl, init_p);
2105  gen_free_list(pdl);
2106 
2107  return t;
2108 }

References c_text_entity(), gen_free_list(), module, and NIL.

Referenced by stub_text().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ c_text_related_entities()

text c_text_related_entities ( entity  module,
list  del,
int  margin,
int  sn,
list ppdl,
list  cl 
)

It is assumed that all entities in list el can be declared by an unique statement, i.e.

their types must be closely related, as in

"int i, *pj, foo();".

But you can also have:

"struct one { struct too {int a;};};"

where no variable is declared. And the parser generate a declaration list stating that "struct two" and "struct one" are declared in this statement.

In other words, this function prints out a C declaration statement, taking into account the derived entities that have to be defined exactly once, pdl. Of course, pdl can be updated by the caller when a derived entity is declared so as to avoid a redeclaration.

At this first level, the declarations of derived types use several lines. If a nested declaration occurs, the nested declaration is packed on a unique line.

List icl indicates for each entity if it should be initialized or not. This is useful for global variable initializations.

If we are not in a compilation unit, the initialization control list is useless and may be wrong because of program transformations such as scalar renaming.

The last entity may be a place holder

overwrite the parser declaration list pdl with del

A declaration has two parts: declaration specifiers and declarator (even with initializer) In declaration specifiers, we can have:

  • storage specifiers : typedef, extern, static, auto, register
  • type specifiers : void, char, short, int, long, float, double, signed, unsigned, struct-or-union specifiers, enum specifier, typedef name
  • type qualifiers : const, restrict, volatile
  • function specifiers : inline

This part is for storage specifiers

&& (extern_p || explicit_extern_entity_p(module, e_last)

|| (extern_entity_p(module, e_last) && !type_functional_p(t_last))))

The global variables stored in static area and in ram but they are not static so a condition is needed, which checks if it is not a global variable

If a derived type is declared first, the qualifiers are carried by the type of the second entity

This part is for type specifiers, type qualifiers, function specifiers and declarator Three special cases for struct/union/enum definitions are treated here. Variable (scalar, array), pointer, function, variables of type struct/union/enum and typedef are treated by function c_words_entity

c = words_variable_or_function(module, e1, true, pc, in_type_declaration, pdl);

the word list pc must have been inserted in text r

Add the declared variables or more declared variables.

add the asm qualifier if needed

the final semi column,

the word list pc must be added to the last sentence of text r

Parameters
moduleodule
delel
marginargin
snn
ppdlpdl
cll

Definition at line 1815 of file declarations.c.

1816 {
1817  /* If we are not in a compilation unit, the initialization control
1818  * list is useless and may be wrong because of program
1819  * transformations such as scalar renaming.
1820  */
1821  bool cu_p = entity_undefined_p(module)?
1822  false :
1824  list icl = ENDP(cl)? NIL : (cu_p? CDR(cl) : NIL);
1825  list el = filtered_declaration_list(del, &icl);
1826  text r = make_text(NIL);
1827  entity e1 = ENTITY(CAR(el)); // Let's use the first declared entity.
1828  const char* name1 = entity_user_name(e1);
1829  type t1 = entity_type(e1);
1830  entity e_last = ENTITY(CAR(gen_last(el))); // Let's also use the last declared entity.
1831  //type t_last = entity_type(e_last);
1832  //storage s1 = entity_storage(e1);
1833  storage s_last = entity_storage(e_last);
1834  //value val1 = entity_initial(e1);
1835  list pc = NIL;
1836  bool space_p = get_bool_property("PRETTYPRINT_LISTS_WITH_SPACES");
1837  bool skip_first_comma_p = true;
1838 
1839  bool place_holder_p = false;
1840  if(gen_length(el)==2) {
1841  /* The last entity may be a place holder */
1842  entity e2 = ENTITY(CAR(CDR(el)));
1843  if(place_holder_variable_p(e2)) {
1844  place_holder_p = true;
1845  }
1846  }
1847 
1848  /* overwrite the parser declaration list pdl with del */
1849  //pdl = del;
1850  // Not a good idea with recursive calls to this function
1851 
1852  pips_assert("the entity list is not empty", gen_length(el)>0);
1853 
1854  pips_debug(5,"Print declaration for first entity %s in module %s\n",
1855  entity_name(e1),
1856  entity_undefined_p(module)? "UNDEFINED" : entity_name(module));
1857 
1858  /* A declaration has two parts: declaration specifiers and declarator (even with initializer)
1859  In declaration specifiers, we can have:
1860  - storage specifiers : typedef, extern, static, auto, register
1861  - type specifiers : void, char, short, int, long, float, double, signed, unsigned,
1862  struct-or-union specifiers, enum specifier, typedef name
1863  - type qualifiers : const, restrict, volatile
1864  - function specifiers : inline */
1865 
1866  /* This part is for storage specifiers */
1867  bool extern_p = false; // so as not to change the default behavior
1868  bool dummy_p = false;
1869  if(!ENDP(cl)) {
1870  expression first = EXPRESSION(CAR(cl));
1871  int ic = integer_constant_expression_value(first);
1872  extern_p = (ic==1 || ic==3)? true : false;
1873  //dummy_p = (ic==2 || ic==3)? true : false;
1874  // FI: the information about dummy_p is not reliable
1875  // several derived entities may be used or declared within one declaration
1876  // statement, but only one flag is stored by the parser...
1877  dummy_p = false;
1878  }
1879  if (!entity_undefined_p(module) && extern_p) {
1880  /* && (extern_p || explicit_extern_entity_p(module, e_last) */
1881  /* || (extern_entity_p(module, e_last) && !type_functional_p(t_last)))) */
1882  pc = CHAIN_SWORD(pc,"extern ");
1883  }
1884 
1885  if (strstr(entity_name(e_last),TYPEDEF_PREFIX) != NULL) {
1886  pc = CHAIN_SWORD(pc,"typedef ");
1887  // FI: too early for typedef17.c
1888  //*ppdl = CONS(ENTITY, e_last, *ppdl);
1889  //if(same_string_p(entity_user_name(e_last), "__gconv_t")) {
1890  // fprintf(stderr, "Entity \"%s\" found.\n", entity_user_name(e_last));
1891  //}
1892  }
1893 
1894  /* The global variables stored in static area and in ram but they
1895  are not static so a condition is needed, which checks if it is not a
1896  global variable*/
1897  // entity m = get_current_module_entity();
1898  if ((storage_ram_p(s_last)
1900  && !strstr(entity_name(e_last),TOP_LEVEL_MODULE_NAME))
1901  || (entity_module_p(e_last) && static_module_p(e_last)))
1902  pc = CHAIN_SWORD(pc,"static ");
1903 
1904  /* If a derived type is declared first, the qualifiers are carried
1905  * by the type of the second entity
1906  */
1907  if(derived_entity_p(e1) && gen_length(el)>1) {
1908  entity e2 = ENTITY(CAR(CDR(el)));
1909  type t2 = entity_type(e2);
1910  if(type_variable_p(t2)) {
1911  variable v2 = type_variable(t2);
1912  list ql2 = variable_qualifiers(v2);
1913  pc = gen_nconc(pc, words_qualifiers(ql2));
1914  }
1915  }
1916 
1917 
1918  /* This part is for type specifiers, type qualifiers, function specifiers and declarator
1919  Three special cases for struct/union/enum definitions are treated here.
1920  Variable (scalar, array), pointer, function, variables of type struct/union/enum and typedef
1921  are treated by function c_words_entity */
1922 
1923  bool in_type_declaration = true;
1924  switch (type_tag(t1)) {
1925  case is_type_struct:
1926  {
1927  list l = type_struct(t1);
1928  const char * lname = entity_local_name(e1);
1929  bool init_p = strstr(lname, STRUCT_PREFIX DUMMY_STRUCT_PREFIX ) != NULL;
1930  if(!init_p)
1931  init_p = !dummy_p && !ENDP(l) && !gen_in_list_p(e1, *ppdl)
1932  && declarable_type_p(t1, *ppdl) && !place_holder_p;
1933  pc = words_struct_reference(name1, pc, init_p);
1935  make_unformatted(NULL,sn,margin,pc)));
1936  if(init_p) {
1937  *ppdl = gen_once(e1, *ppdl);
1938  text fields = c_text_entities(module, l, margin+INDENTATION, ppdl);
1939  pc = CHAIN_SWORD(NIL, "{");
1940  add_words_to_text(r, pc);
1941  MERGE_TEXTS(r, fields);
1943  }
1944  break;
1945  }
1946  case is_type_union:
1947  {
1948  list l = type_union(t1);
1949  const char * lname = entity_local_name(e1);
1950  bool init_p = strstr(lname, UNION_PREFIX DUMMY_UNION_PREFIX ) != NULL;
1951  if(!init_p)
1952  init_p = !dummy_p && !ENDP(l) && !gen_in_list_p(e1, *ppdl)
1953  && declarable_type_p(t1, *ppdl) && !place_holder_p;
1954  pc = words_union(name1, pc, init_p);
1956  make_unformatted(NULL,sn,margin,pc)));
1957  if(init_p) {
1958  *ppdl = gen_once(e1, *ppdl);
1959  text fields = c_text_entities(module,l,margin+INDENTATION, ppdl);
1960  pc = CHAIN_SWORD(NIL, "{");
1961  add_words_to_text(r, pc);
1962  MERGE_TEXTS(r,fields);
1964  }
1965  break;
1966  }
1967  case is_type_enum:
1968  {
1969  list l = type_enum(t1);
1970  const char * lname = entity_local_name(e1);
1971  bool init_p = strstr( lname, ENUM_PREFIX DUMMY_ENUM_PREFIX ) != NULL;
1972  if(!init_p)
1973  init_p = !dummy_p && !ENDP(l) && !gen_in_list_p(e1, *ppdl)
1974  && declarable_type_p(t1, *ppdl) && !place_holder_p;
1975  if(init_p) {
1976  *ppdl = gen_once((void *) e1, *ppdl);
1977  pc = words_enum(name1, l, space_p, pc, ppdl);
1979  make_unformatted(NULL,sn,margin,pc)));
1980  }
1981  else {
1982  pc = words_enum_reference(name1, pc, init_p);
1984  make_unformatted(NULL,sn,margin,pc)));
1985  }
1986  break;
1987  }
1988  case is_type_variable:
1989  case is_type_functional:
1990  case is_type_void:
1991  case is_type_unknown:
1992  {
1993  /*pc = words_variable_or_function(module, e1, true, pc,
1994  in_type_declaration, pdl);*/
1995  in_type_declaration=false;
1996 
1997  bool init_p = extern_p? false : true;
1998  if(!ENDP(icl)) {
1999  expression ice = EXPRESSION(CAR(icl)); // Initialization control expression
2000  int ic = integer_constant_expression_value(ice);
2001  init_p = ic==1? true : false;
2002  }
2003 
2004  pc = words_variable_or_function(module, e1, true, pc,
2005  in_type_declaration, ppdl, init_p);
2007  make_unformatted(NULL,sn,margin,pc)));
2008  skip_first_comma_p = false;
2009  break;
2010  }
2011  case is_type_varargs:
2012  case is_type_statement:
2013  case is_type_area:
2014  default:
2015  pips_internal_error("unexpected type tag");
2016  }
2017 
2018  /* the word list pc must have been inserted in text r*/
2019  pc = NIL;
2020 
2021 
2022 
2023  /* Add the declared variables or more declared variables. */
2024  list oel = list_undefined; // other entities after e1
2025  if(place_holder_p)
2026  oel = CDR(CDR(el)); // skip the place holder variable
2027  else
2028  oel = CDR(el);
2029  //print_entities(oel);
2030  list oicl = ENDP(icl) ? NIL : CDR(icl);
2031  FOREACH(ENTITY, e, oel) {
2032  if(skip_first_comma_p) {
2033  skip_first_comma_p = false;
2034  pc = gen_nconc(pc,CHAIN_SWORD(NIL, " "));
2035  }
2036  else
2037  pc = gen_nconc(pc,CHAIN_SWORD(NIL,space_p? ", " : ","));
2038  bool init_p = true;
2039  if(!ENDP(oicl)) {
2040  expression ice = EXPRESSION(CAR(oicl)); // Initialization control expression
2041  int ic = integer_constant_expression_value(ice);
2042  init_p = ic==1? true : false;
2043  POP(oicl);
2044  }
2045  pc = words_variable_or_function(module, e, false, pc, in_type_declaration,
2046  ppdl, init_p);
2047  }
2048  /* add the asm qualifier if needed */
2049  string asm_qual = strdup("");
2051  if(qualifier_asm_p(q)) {
2052  asprintf(&asm_qual,"%s __asm(%s)", asm_qual, qualifier_asm(q));
2053  }
2054  }
2055  pc = CHAIN_SWORD(pc,asm_qual);
2056  free(asm_qual);
2057  /* the final semi column,*/
2058  pc = CHAIN_SWORD(pc,";");
2059 
2060  /* the word list pc must be added to the last sentence of text r */
2061  if(ENDP(text_sentences(r))) {
2062  pips_internal_error("Unexpected empty text");
2063  }
2064  else {
2065  add_words_to_text(r, pc);
2066  }
2067 
2068  if (strstr(entity_name(e_last),TYPEDEF_PREFIX) != NULL) {
2069  *ppdl = CONS(ENTITY, e_last, *ppdl);
2070  }
2071 
2072  return r;
2073 }
unformatted make_unformatted(string a1, intptr_t a2, intptr_t a3, list a4)
Definition: text.c:149
sentence make_sentence(enum sentence_utype tag, void *val)
Definition: text.c:59
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
void free(void *)
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
size_t gen_length(const list l)
Definition: list.c:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
list gen_last(list l)
Return the last element of a list.
Definition: list.c:578
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define asprintf
Definition: misc-local.h:225
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
#define TYPEDEF_PREFIX
Definition: naming-local.h:62
#define ENUM_PREFIX
Definition: naming-local.h:60
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
#define true
Definition: newgen_types.h:81
#define false
Definition: newgen_types.h:80
static list words_variable_or_function(entity module, entity e, bool is_first, list pc, bool in_type_declaration, list *ppdl, bool init_p)
text c_text_entities(entity module, list ldecl, int margin, list *ppdl)
Generate declarations for a list of entities belonging to the same statement declaration.
static list words_enum_reference(const char *name1, list pc, bool init_p)
Prolog to print out a struct definition, such as "struct s { int a; int b;}"; for the time being,...
static list words_enum(const char *name1, list l, bool space_p, list pc, list *ppdl)
list words_qualifiers(list obj)
Definition: declarations.c:795
static list words_union(const char *name1, list pc, bool init_p)
static list filtered_declaration_list(list del, list *pcl)
Fix the declaration list produced by the parser, which includes declared program variables but also d...
static list words_struct_reference(const char *name1, list pc, bool init_p)
To print out a struct reference, such as "struct s".
#define INDENTATION
bool static_area_p(entity aire)
Definition: area.c:77
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
list entity_qualifiers(entity e)
return the qualifiers associated to entity e if it's a variable NIL otherwise
Definition: entity.c:1394
bool entity_module_p(entity e)
Definition: entity.c:683
bool derived_entity_p(entity e)
Definition: entity.c:1048
int integer_constant_expression_value(expression e)
Definition: expression.c:1545
bool static_module_p(entity e)
Check if the given module entity is a static module.
Definition: module.c:80
bool compilation_unit_entity_p(entity e)
Check if the given module entity is a compilation unit.
Definition: module.c:87
bool place_holder_variable_p(entity)
Definition: variable.c:2069
bool declarable_type_p(type, list)
Are all types necessary to define fully type "t" listed in list "pdl"?
Definition: type.c:4361
#define type_struct(x)
Definition: ri.h:2964
#define QUALIFIER(x)
QUALIFIER.
Definition: ri.h:2106
#define type_tag(x)
Definition: ri.h:2940
#define storage_ram_p(x)
Definition: ri.h:2519
#define qualifier_asm_p(x)
Definition: ri.h:2194
#define ram_section(x)
Definition: ri.h:2249
#define entity_undefined_p(x)
Definition: ri.h:2762
#define type_enum(x)
Definition: ri.h:2970
#define qualifier_asm(x)
Definition: ri.h:2196
#define variable_qualifiers(x)
Definition: ri.h:3124
#define storage_ram(x)
Definition: ri.h:2521
@ is_type_varargs
Definition: ri.h:2902
@ is_type_void
Definition: ri.h:2904
@ is_type_enum
Definition: ri.h:2907
@ is_type_statement
Definition: ri.h:2898
@ is_type_functional
Definition: ri.h:2901
@ is_type_variable
Definition: ri.h:2900
@ is_type_union
Definition: ri.h:2906
@ is_type_area
Definition: ri.h:2899
@ is_type_unknown
Definition: ri.h:2903
@ is_type_struct
Definition: ri.h:2905
#define type_variable_p(x)
Definition: ri.h:2947
#define type_union(x)
Definition: ri.h:2967
char * strdup()
static int lname(char *s, int look_for_entry)
check for keywords for subprograms return 0 if comment card, 1 if found name and put in arg string.
Definition: split_file.c:283
#define CHAIN_SWORD(l, s)
#define MAKE_ONE_WORD_SENTENCE(m, s)
#define ADD_SENTENCE_TO_TEXT(t, p)
void add_words_to_text(text, list)
Add the word list wl to the end of the last sentence of text t.
Definition: util.c:273
#define text_sentences(x)
Definition: text.h:113
@ is_sentence_unformatted
Definition: text.h:58

References ADD_SENTENCE_TO_TEXT, add_words_to_text(), asprintf, c_text_entities(), CAR, CDR, CHAIN_SWORD, compilation_unit_entity_p(), CONS, declarable_type_p(), derived_entity_p(), DUMMY_ENUM_PREFIX, DUMMY_STRUCT_PREFIX, DUMMY_UNION_PREFIX, ENDP, ENTITY, entity_local_name(), entity_module_p(), entity_name, entity_qualifiers(), entity_storage, entity_type, entity_undefined_p, entity_user_name(), ENUM_PREFIX, EXPRESSION, false, filtered_declaration_list(), FOREACH, free(), gen_in_list_p(), gen_last(), gen_length(), gen_nconc(), gen_once(), get_bool_property(), INDENTATION, integer_constant_expression_value(), is_sentence_unformatted, is_type_area, is_type_enum, is_type_functional, is_type_statement, is_type_struct, is_type_union, is_type_unknown, is_type_varargs, is_type_variable, is_type_void, list_undefined, lname(), MAKE_ONE_WORD_SENTENCE, make_sentence(), make_text(), make_unformatted(), MERGE_TEXTS, module, NIL, pips_assert, pips_debug, pips_internal_error, place_holder_variable_p(), POP, QUALIFIER, qualifier_asm, qualifier_asm_p, ram_section, static_area_p(), static_module_p(), storage_ram, storage_ram_p, strdup(), STRUCT_PREFIX, text_sentences, TOP_LEVEL_MODULE_NAME, true, type_enum, type_struct, type_tag, type_union, type_variable, type_variable_p, TYPEDEF_PREFIX, UNION_PREFIX, variable_qualifiers, words_enum(), words_enum_reference(), words_qualifiers(), words_struct_reference(), words_union(), and words_variable_or_function().

Referenced by c_text_entity().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ c_words_entity()

list c_words_entity ( type  t,
list  name,
list ppdl 
)
Parameters
nameame
ppdlpdl

Definition at line 1421 of file declarations.c.

1422 {
1423  list pc = generic_c_words_entity(t, name, false, false, ppdl);
1424 
1425  ifdebug(8) {
1426  string s = list_to_string(pc);
1427  pips_debug(8, "End with \"\%s\"\n", s);
1428  }
1429 
1430  return pc;
1431 }
string list_to_string(list l)
Return the malloc()ed version of the concatenation of all the strings in the list.
Definition: args.c:74
list generic_c_words_entity(type t, list name, bool is_safe, bool add_dummy_parameter_name_p, list *ppdl)
This recursive function prints a C variable with its type.
Definition: declarations.c:980
#define ifdebug(n)
Definition: sg.c:47

References generic_c_words_entity(), ifdebug, list_to_string(), and pips_debug.

Referenced by ensure_comment_consistency(), generic_c_words_simplified_entity(), UpdatePointerEntity(), words_basic(), and words_parameters().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ c_words_simplified_entity()

list c_words_simplified_entity ( type  t,
list  name,
bool  is_first,
bool  in_type_declaration,
list ppdl 
)

The declaration list pointer ppdl is passed down to determine if an internal derived type must be fully expanded within another declaration or not.

If it is declared by itself, there is no need to expand its declaration again.

Parameters
nameame
is_firsts_first
in_type_declarationn_type_declaration
ppdlpdl

Definition at line 1408 of file declarations.c.

1409 {
1410  list pc = generic_c_words_simplified_entity(t, name, false, false, is_first,
1411  in_type_declaration, false, ppdl);
1412 
1413  ifdebug(8) {
1414  string s = list_to_string(pc);
1415  pips_debug(8, "End with \"\%s\"\n", s);
1416  }
1417 
1418  return pc;
1419 }
list generic_c_words_simplified_entity(type t, list name, bool is_safe, bool add_dummy_parameter_name_p, bool is_first, bool in_type_declaration, bool argument_p, list *ppdl)
Same as above, but the bool is_first is used to skip a type specifier which is useful when several va...

References generic_c_words_simplified_entity(), ifdebug, list_to_string(), and pips_debug.

Referenced by ensure_comment_consistency(), and words_variable_or_function().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ filtered_declaration_list()

static list filtered_declaration_list ( list  del,
list pcl 
)
static

Fix the declaration list produced by the parser, which includes declared program variables but also derived types used in the declaration or the initialization, to accomodate the prettyprinter, which must decide which derived types appearing in the declaration must be defined, and which one must be referenced:

  • first option: get rid of all derived entities; pro: safe; cons: all declarations become one liners
  • second option: get rid of all derived entities but the last one, assuming they appear in the right order. Sometimes, you may even have to get rid of all derived entities.

All entities in del are useful to regenerate the corresponding declaration, but the key entities are the type used for the variables, and the variables. Nested types should not appear in the return list.

FI: I wonder what the parser generates for something like

int foo[sizeof(struct {int a; int b;})] = {...};

No new list is allocated, just a pointer to the first relevant chunk of del.

Filter out secondary types

Filter out initialization flags

FI: initially I assumed > 2 for pattern such as

struct {struct ..} x;

but you can also have a struct declaration:

struct {struct ..};

with no variable declaration. Or a declaration in the rhs via a sizeof or a cast... See below, after the intermediate list.

Maybe, some type related entities such as substructure should not be printed out. Only the last one is useful.

Now we still have to deal with "void * p = ... derived type definition(s)..." Maybe, we simply want to make sure that e1 belongs to type supporting entities of t2... but this is not strong enough because it includes types of formal arguments which are not relevant

If t2 is a pointer, get to the final pointed type.

If nt2 is a functional type, what is the final pointed type returned?

program transformations do not know yet about the prettyprint control list. Let's keep the first element for extern and truncate what's behind, the initialization control list.

Definition at line 1671 of file declarations.c.

1672 {
1673  /* Filter out secondary types */
1674  list el = del;
1675  /* Filter out initialization flags */
1676  bool foif_p = !ENDP(*pcl);
1677 
1678  ifdebug(8) {
1679  pips_debug(8, "Input declaration list: ");
1680  print_entities(del);
1681  fprintf(stderr, "\n");
1682  }
1683 
1684  /* FI: initially I assumed > 2 for pattern such as
1685 
1686  struct {struct ..} x;
1687 
1688  but you can also have a struct declaration:
1689 
1690  struct {struct ..};
1691 
1692  with no variable declaration. Or a declaration in the rhs via a
1693  sizeof or a cast... See below, after the intermediate list.
1694 
1695  */
1696  if(gen_length(del)>=2) {
1697  /* Maybe, some type related entities such as substructure should
1698  not be printed out. Only the last one is useful. */
1699  entity e_previous = ENTITY(CAR(del));
1700 
1701  if(entity_struct_p(e_previous)
1702  ||entity_union_p(e_previous)
1703  ||entity_enum_p(e_previous)) {
1704  FOREACH(ENTITY, e, CDR(del)) {
1705  if(entity_struct_p(e)
1706  ||entity_union_p(e)
1707  ||entity_enum_p(e)) {
1708  POP(el);
1709  if(foif_p)
1710  POP(*pcl);
1711  }
1712  else {
1713  break;
1714  }
1715  }
1716  }
1717  }
1718 
1719  ifdebug(8) {
1720  pips_debug(8, "Intermediate declaration list: ");
1721  print_entities(el);
1722  fprintf(stderr, "\n");
1723  }
1724 
1725  /* Now we still have to deal with "void * p = ... derived type
1726  definition(s)..." Maybe, we simply want to make sure that e1
1727  belongs to type supporting entities of t2... but this is not
1728  strong enough because it includes types of formal arguments which
1729  are not relevant
1730  */
1731  if(gen_length(el)>=2) {
1732  entity e1 = ENTITY(CAR(el));
1733 
1734  if(derived_entity_p(e1)) {
1735  bool match_p = false;
1736  //type t1 = entity_type(e1);
1737  entity e2 = ENTITY(CAR(CDR(el)));
1738  type t2 = entity_type(e2);
1739  type nt2 = type_undefined;
1740 
1741  /* If t2 is a pointer, get to the final pointed type. */
1742  nt2 = type_to_final_pointed_type(t2);
1743 
1744  /* If nt2 is a functional type, what is the final pointed type
1745  returned? */
1746  if(type_functional_p(nt2)) {
1747  functional f2 = type_functional(nt2);
1748  type rt2 = functional_result(f2);
1749  nt2 = type_to_final_pointed_type(rt2);
1750  }
1751 
1752  if(type_variable_p(nt2)) {
1754  if(basic_derived_p(b2) && basic_derived(b2)==e1)
1755  match_p = true;
1756  }
1757  if(!match_p) {
1758  POP(el);
1759  if(foif_p)
1760  POP(*pcl);
1761  }
1762  }
1763  }
1764 
1765  ifdebug(8) {
1766  pips_debug(8, "Output declaration list: ");
1767  print_entities(el);
1768  fprintf(stderr, "\n");
1769  }
1770 
1771  if(!(ENDP(*pcl) || gen_length(el)==gen_length(*pcl))) {
1773  if(!compilation_unit_entity_p(m)) {
1774  /* program transformations do not know yet about the prettyprint
1775  control list. Let's keep the first element for extern and
1776  truncate what's behind, the initialization control list. */
1777  gen_free_list(CDR(*pcl));
1778  CDR(*pcl) = NIL;
1779  }
1780  else {
1781  pips_assert("The control list is empty or the two lists have the same "
1782  "number of elements",
1783  ENDP(*pcl) || gen_length(el)==gen_length(*pcl));
1784  }
1785  }
1786 
1787  return el;
1788 }
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
int f2(int off1, int off2, int w, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:1
bool entity_struct_p(entity e)
Is entity e the entity corresponding to a struct declaration?
Definition: entity.c:1002
bool entity_enum_p(entity e)
Definition: entity.c:968
void print_entities(list l)
Definition: entity.c:167
bool entity_union_p(entity e)
Is entity e an entity representing the union declaration?
Definition: entity.c:1038
type type_to_final_pointed_type(type)
returns t if t is not a pointer type, and the first indirectly pointed type that is not a pointer if ...
Definition: type.c:5336
#define type_functional_p(x)
Definition: ri.h:2950
#define functional_result(x)
Definition: ri.h:1444
#define type_functional(x)
Definition: ri.h:2952
#define basic_derived_p(x)
Definition: ri.h:638
#define type_undefined
Definition: ri.h:2883
Value b2
Definition: sc_gram.c:105
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...

References b2, basic_derived, basic_derived_p, CAR, CDR, compilation_unit_entity_p(), derived_entity_p(), ENDP, ENTITY, entity_enum_p(), entity_struct_p(), entity_type, entity_union_p(), f2(), FOREACH, fprintf(), functional_result, gen_free_list(), gen_length(), get_current_module_entity(), ifdebug, NIL, pips_assert, pips_debug, POP, print_entities(), type_functional, type_functional_p, type_to_final_pointed_type(), type_undefined, type_variable, type_variable_p, and variable_basic.

Referenced by c_text_related_entities().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ generic_c_words_entity()

list generic_c_words_entity ( type  t,
list  name,
bool  is_safe,
bool  add_dummy_parameter_name_p,
list ppdl 
)

This recursive function prints a C variable with its type.

It can be a simple variable declaration such as "int a" or complicated one such as "int (* forces[10])()" (an array of 10 pointers, each pointer points to a function with no parameter and the return type is int).

Type "t" is recursively traversed and the obtained attribute are accumulated in the list "name" (name of the type, not name of the variable).

Purpose of "is_safe"? Seems to be passed down recursively but never to be used...

In C, functional type can be decorated by optional dummy parameter names.

Parameters
nameame
is_safes_safe
add_dummy_parameter_name_pdd_dummy_parameter_name_p
ppdlpdl

Definition at line 980 of file declarations.c.

981 {
982 // If this function is still used, NIL should be replaced by the
983 // module declaration list
984  return generic_c_words_simplified_entity(t, name, is_safe,
985  add_dummy_parameter_name_p,
986  true, false, false, ppdl);
987 }

References generic_c_words_simplified_entity().

Referenced by c_words_entity(), safe_c_words_entity(), and stub_text().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ generic_c_words_simplified_entity()

list generic_c_words_simplified_entity ( type  t,
list  name,
bool  is_safe,
bool  add_dummy_parameter_name_p,
bool  is_first,
bool  in_type_declaration,
bool  argument_p,
list ppdl 
)

Same as above, but the bool is_first is used to skip a type specifier which is useful when several variables or types are defined in a unique statement such as "int i, *pi, ai[10],...;".

type t: new type to add in front of the word list name

list name: later part of the declaration being built

bool is_safe: does not seem to be used anymore

bool add_dummy_parameter_name_p: for function declarations, add a dummy parameter name to the type of each formal parameter

bool is_first: prettyprint the qualifiers or not; they should be printed only once when they apply to several declarations as in:

"register int i, j;"

in_type_declaration is set to true when a variable is declared at the same time as its type

argument_p: the type is used as argument type in a function declaration

list ppdl: pointer to the declaration list to decide if data structures appearing in another data structure must be declared independently or not. See validation cases struct03.c, struct04.c and struct05.c.

Function name is an expression like *vfs[] in (*vfs[])() (syntax = application), or an abstract function type, so parentheses must be added

Function name is a simple reference

RK wants us to use another better function than i2a, but its name is not documented next to i2a() source code and here the string is going to be strduped, which makes i2a() a better choice.

ips_debug(3,"Parameter type %s\n ", type_undefined_p(t1)? "type_undefined" : words_to_string(words_type(t1, ppdl, true)));

c_words_entity(t1,NIL) should be replaced by c_words_entity(t1,name_of_corresponding_parameter)

Add type qualifiers if there are

FI: left out of the previous declaration internal representation

&& !qualifiers_p

Array name is an expression like __ctype+1 in (__ctype+1)[*np] (syntax = subscript), or abstract type, parentheses must be added

Array name is a simple reference

The derived type has been declared explicitly elsewhere: see struct05.c

The derived type is declared by itself

Do not recurse down if the derived type reference itself

A place holder variable has no name and require no space

This section is derived from c_text_entity()

it is used for structures, unions and enums which have no names because they are part of a more global declaration such as typedef s

FI: The union and the struct cases could be merged.

Parameters
nameame
is_safes_safe
add_dummy_parameter_name_pdd_dummy_parameter_name_p
is_firsts_first
in_type_declarationn_type_declaration
argument_prgument_p
ppdlpdl

Definition at line 1017 of file declarations.c.

1018 {
1019  list pc = NIL;
1020  bool space_p = get_bool_property("PRETTYPRINT_LISTS_WITH_SPACES");
1021 
1022  if(type_undefined_p(t)) {
1023  pc = CHAIN_SWORD(NIL, "type_undefined");
1024  pc = gen_nconc(pc,name);
1025  return pc;
1026  }
1027 
1028  if (type_functional_p(t))
1029  {
1031  type t2 = functional_result(f);
1033  list cparam = list_undefined;
1034  bool first = true;
1035  int pnum;
1036 
1037  pips_debug(9,"Function type with name = \"%s\" and length %zd\n",
1038  list_to_string(name), gen_length(name));
1039 
1040  if ((gen_length(name) > 1)
1041  || ((gen_length(name) == 1) && (strcmp(STRING(CAR(name)),"*")==0)))
1042  {
1043  /* Function name is an expression like *vfs[] in (*vfs[])()
1044  (syntax = application), or an abstract function type, so
1045  parentheses must be added */
1046  pc = CHAIN_SWORD(NIL,"(");
1047  pc = gen_nconc(pc,name);
1048  pc = CHAIN_SWORD(pc,")(");
1049 
1050  }
1051  else
1052  {
1053  /* Function name is a simple reference */
1054  pc = CHAIN_SWORD(name,"(");
1055  }
1056 
1058  for(cparam = lparams, pnum = 1; !ENDP(cparam); POP(cparam), pnum++) {
1059  parameter p = PARAMETER(CAR(cparam));
1060  type t1 = parameter_type(p);
1061  string pn = dummy_unknown_p(parameter_dummy(p))?
1064 
1065  if(add_dummy_parameter_name_p
1066  && string_undefined_p(pn)
1067  && !type_varargs_p(t1)
1068  && !type_void_p(t1)) {
1069  /* RK wants us to use another better function than i2a, but
1070  its name is not documented next to i2a() source code and
1071  here the string is going to be strduped, which makes
1072  i2a() a better choice. */
1073  pn = concatenate("f", i2a(pnum), NULL);
1074  }
1075 
1076  /*pips_debug(3,"Parameter type %s\n ",
1077  type_undefined_p(t1)? "type_undefined" :
1078  words_to_string(words_type(t1, ppdl, true))); */
1079  if (!first)
1080  pc = gen_nconc(pc,CHAIN_SWORD(NIL, space_p? ", " : ","));
1081  /* c_words_entity(t1,NIL) should be replaced by c_words_entity(t1,name_of_corresponding_parameter) */
1082  pc = gen_nconc(pc,
1084  string_undefined_p(pn)? NIL : CONS(STRING, strdup(pn), NIL),
1085  is_safe, false, true,in_type_declaration, true, ppdl));
1086  pips_debug(9,"List of parameters \"%s\"\n ",list_to_string(pc));
1087  first = false;
1088  }
1089  }
1090 
1091  pc = CHAIN_SWORD(pc,")");
1092  return generic_c_words_simplified_entity(t2, pc, is_safe, false,
1093  is_first, in_type_declaration,
1094  argument_p, ppdl);
1095  }
1096 
1097  if (pointer_type_p(t))
1098  {
1100  pips_debug(9,"Pointer type with name = %s\n", list_to_string(name));
1101 
1102  /*
1103  * No space : it's only "after a comma to separate items in lists such as
1104  * declaration lists or parameter lists in order to improve readability"
1105  *
1106  * FI: a space would be useful sometimes to separate "*" from an
1107  * identifier in "char *foo(void)" to obtain "char * foo(void)"
1108  * instead, but not "char * * foo(void)" nor "void foo(char * )".
1109  */
1110  // pc = CHAIN_SWORD(NIL, space_p? "*":"*");
1111  pc = CHAIN_SWORD(NIL, "*");
1112  // FI: qualifiers for type t1 are dealt with at a lower level,
1113  // qualifiers for type t are dealt here
1114  variable var = type_variable(t);
1115  list ql = variable_qualifiers(var);
1116  if (qualifiers_const_p(ql) || qualifiers_restrict_p(ql)) {
1118  // We may have other qualifiers which must be output somewhere
1119  // else, for instance "register"
1120  /*
1121  pc = gen_nconc(pc,
1122  words_qualifiers(variable_qualifiers(type_variable(t))));
1123  */
1124  }
1125  pc = gen_nconc(pc,name);
1126  pc = generic_c_words_simplified_entity(t1, pc, is_safe, false,
1127  is_first, in_type_declaration,
1128  argument_p, ppdl);
1129  pc = gen_nconc(words_initial_qualifiers(ql), pc);
1130  return pc;
1131  }
1132 
1133  /* Add type qualifiers if there are */
1134  bool qualifiers_p = false;
1135  if (false && ( is_first || in_type_declaration )
1136  && type_variable_p(t)
1139  qualifiers_p = true;
1140  }
1141  else if (false && ( is_first || in_type_declaration )
1142  && type_void_p(t)
1143  && type_void(t) != NIL)
1144  pc = words_qualifiers(type_void(t));
1145 
1146  if (basic_type_p(t)) {
1147  string sname = list_to_string(name);
1148  pips_debug(9,"Basic type with name = \"%s\"\n", sname);
1149 
1150  if(is_first) {
1151  pc = gen_nconc(pc,words_type(t, ppdl, argument_p));
1152  }
1153  if (string_type_p(t)) {
1154  // pc = CHAIN_SWORD(pc," *");
1155  ;
1156  }
1157  /* FI: left out of the previous declaration internal representation */
1158  if(strlen(sname)!=0 && is_first/* && !qualifiers_p*/)
1159  pc = CHAIN_SWORD(pc," ");
1160  if(!bit_type_p(t) || (strstr(sname,DUMMY_MEMBER_PREFIX)==NULL)) {
1161  pc = gen_nconc(pc,name);
1162  }
1163  free(sname);
1164  if (bit_type_p(t)) {
1167  list iew = words_expression(ie, ppdl);
1168  pc = CHAIN_SWORD(pc,":");
1169  pc = gen_nconc(pc, iew);
1170  }
1171  return pc;
1172  }
1173  if (array_type_p(t)) {
1174  variable var = type_variable(t);
1175  list dims = variable_dimensions(var);
1176  list ql = variable_qualifiers(var);
1177  type t1 = copy_type(t);
1178  list tmp = NIL;
1179  pips_debug(9,"Array type with name = %s\n", list_to_string(name));
1180 
1181  if ((gen_length(name) > 1) || ((gen_length(name) == 1) && (strcmp(STRING(CAR(name)),"*")==0)))
1182  {
1183  /* Array name is an expression like __ctype+1 in (__ctype+1)[*np]
1184  (syntax = subscript), or abstract type, parentheses must be added */
1185  tmp = CHAIN_SWORD(tmp,"(");
1186  tmp = gen_nconc(tmp,name);
1187  tmp = CHAIN_SWORD(tmp,")");
1188  }
1189  else
1190  {
1191  /* Array name is a simple reference */
1192  tmp = name;
1193  }
1196  // FI: I understand why the dimension information has to be
1197  // removed, I so not understand why the qualifiers have to be
1198  // removed too
1201  pips_debug(8, "Before concatenation, pc=\"\%s\"\n", list_to_string(pc));
1202  if(pc!=NIL && !qualifiers_p)
1203  pc = CHAIN_SWORD(pc, " ");
1204  list ret =
1205  gen_nconc(pc,
1207  is_safe, false, is_first,
1208  in_type_declaration,
1209  argument_p,
1210  ppdl));
1212  free_type(t1);
1213  return ret;
1214  }
1215 
1216  if (derived_type_p(t))
1217  {
1218  variable v = type_variable(t);
1219  basic b = variable_basic(v);
1220  list ql = variable_qualifiers(v);
1221  entity ent = basic_derived(b);
1222  if(is_first) {
1223  type t1 = entity_type(ent);
1224  string n = entity_name(ent);
1225  pips_debug(9,"Derived type with name = %s\n", list_to_string(name));
1226  if((strstr(n,ENUM_PREFIX DUMMY_ENUM_PREFIX)==NULL)
1227  &&(strstr(n,STRUCT_PREFIX DUMMY_STRUCT_PREFIX)==NULL)
1228  &&(strstr(n,UNION_PREFIX DUMMY_UNION_PREFIX)==NULL)) {
1229  if(gen_in_list_p((void *) ent, *ppdl) // previously defined
1230  || !declarable_type_p(t1, *ppdl) // not definable yet
1231  // FI: it might be better to pass down an extra parameter
1232  // rather than deduce this from name
1233  || (!ENDP(name) && same_string_p(STRING(CAR(name)), ""))) { // "struct s;" case
1234  /* The derived type has been declared explicitly
1235  elsewhere: see struct05.c */
1236  pc = gen_nconc(pc,words_type(t1, ppdl, argument_p));
1237  pc = CHAIN_SWORD(pc," ");
1238  pc = CHAIN_SWORD(pc,entity_user_name(ent));
1239  }
1240  else {
1241  /* The derived type is declared by itself*/
1242  const char* name = entity_user_name(ent);
1243  list epc = NIL;
1244  /* Do not recurse down if the derived type reference
1245  itself */
1246  *ppdl = gen_once((void *) ent, *ppdl);
1247  epc =
1249  CHAIN_SWORD(NIL,name),
1250  is_safe,
1251  add_dummy_parameter_name_p,
1252  is_first, in_type_declaration,
1253  argument_p, ppdl);
1254  pc = gen_nconc(pc, epc);
1255  //gen_free_list(npdl);
1256  }
1257  if(!ENDP(ql))
1258  pc = gen_nconc(words_qualifiers(ql), pc);
1259  }
1260  else {
1261  //pc = CHAIN_SWORD(pc,"problem!");
1262  pc = c_words_entity(t1, pc, ppdl);
1263  }
1264  /* A place holder variable has no name and require no space */
1265  if(gen_length(name)==1 && same_string_p(STRING(CAR(name)),""))
1266  ;
1267  else
1268  pc = CHAIN_SWORD(pc," ");
1269  }
1270  return gen_nconc(pc,name);
1271  }
1272  if (typedef_type_p(t))
1273  {
1274  if(is_first) {
1275  // FI: type_variable_p() is always true?
1276  variable var = type_variable(t);
1277  list ql = variable_qualifiers(var);
1278  basic b = variable_basic(var);
1279  entity ent = basic_typedef(b);
1280  pips_debug(9,"Typedef type with name = \"\%s\"\n",
1281  list_to_string(name));
1282  pc = CHAIN_SWORD(pc, entity_user_name(ent));
1283  pc = gen_nconc(words_qualifiers(ql), pc);
1284  if(name!=NIL)
1285  pc = CHAIN_SWORD(pc," ");
1286  }
1287  return gen_nconc(pc,name);
1288  }
1289  if (type_varargs_p(t))
1290  {
1291  pips_debug(9,"Varargs type ... with name = %s\n", list_to_string(name));
1292  pc = CHAIN_SWORD(pc,"...");
1293  return gen_nconc(pc,name);
1294  }
1295  /* This section is derived from c_text_entity() */
1296  /* it is used for structures, unions and enums which have no names
1297  because they are part of a more global declaration such as
1298  typedef s*/
1299  /* FI: The union and the struct cases could be merged. */
1300  if(type_struct_p(t))
1301  {
1302  list l = type_struct(t);
1303  string sname = list_to_string(name);
1304  list cl = list_undefined;
1305 
1306  pips_debug(9,"Struct type ... with name = %s\n", sname);
1307 
1308  pc = CHAIN_SWORD(pc,"struct ");
1309  // hmmm... name may be an empty list... and the sname test seems true
1310  if(name && strstr(sname,DUMMY_STRUCT_PREFIX)==NULL) {
1311  pc = gen_nconc(pc,name);
1312  if(!ENDP(l))
1313  pc = CHAIN_SWORD(pc," ");
1314  }
1315  free(sname);
1316  if(!ENDP(l)) {
1317  pc = CHAIN_SWORD(pc,"{");
1318 
1319  for(cl = l; !ENDP(cl); POP(cl)) {
1320  entity sm = ENTITY(CAR(cl));
1321  type tsm = entity_type(sm);
1322  pc = gen_nconc(pc,c_words_entity(tsm,CHAIN_SWORD(NIL,entity_user_name(sm)), ppdl));
1323  if(ENDP(CDR(cl)))
1324  pc = CHAIN_SWORD(pc,";");
1325  else
1326  pc = CHAIN_SWORD(pc,"; ");
1327  }
1328  pc = CHAIN_SWORD(pc,"}");
1329  }
1330  return pc;
1331  }
1332  if(type_union_p(t))
1333  {
1334  list l = type_union(t);
1335  string sname = list_to_string(name);
1336  list cl = list_undefined;
1337 
1338  pips_debug(9,"Union type ... with name = %s\n", sname);
1339 
1340  pc = CHAIN_SWORD(pc,"union ");
1341  //if(strstr(sname,DUMMY_UNION_PREFIX)==NULL) {
1342  // pc = gen_nconc(pc,name);
1343  // pc = CHAIN_SWORD(pc," ");
1344  //}
1345  free(sname);
1346  pc = CHAIN_SWORD(pc,"{");
1347 
1348  for(cl = l; !ENDP(cl); POP(cl)) {
1349  entity eu = ENTITY(CAR(cl));
1350  type tu = entity_type(eu);
1351  pc = gen_nconc(pc,c_words_entity(tu,CHAIN_SWORD(NIL,entity_user_name(eu)), ppdl));
1352  if(ENDP(CDR(cl)))
1353  pc = CHAIN_SWORD(pc,";");
1354  else
1355  pc = CHAIN_SWORD(pc,"; ");
1356  }
1357  pc = CHAIN_SWORD(pc,"}");
1358  return pc;
1359  }
1360  if(type_enum_p(t))
1361  {
1362  list l = type_enum(t);
1363  bool first = true;
1364  string sname = list_to_string(name);
1365  list cl = list_undefined;
1366  int cv = 0;
1367 
1368  pips_debug(9,"Enum type ... with name = %s\n", sname);
1369 
1370  pc = CHAIN_SWORD(pc,"enum ");
1371  if(strstr(sname,DUMMY_ENUM_PREFIX)==NULL && !same_string_p(sname,"")) {
1372  pc = gen_nconc(pc,name);
1373  pc = CHAIN_SWORD(pc," ");
1374  }
1375  free(sname);
1376  pc = CHAIN_SWORD(pc,"{");
1377 
1378  for(cl = l; !ENDP(cl); POP(cl)) {
1379  entity em = ENTITY(CAR(cl));
1380  value emv = entity_initial(em);
1381  symbolic ems = value_symbolic(emv);
1382  expression eme = symbolic_expression(ems);
1384  int n = constant_int(emc);
1385 
1386  if (!first)
1387  pc = CHAIN_SWORD(pc, space_p? ", " : ",");
1388  pc = CHAIN_SWORD(pc, entity_user_name(em));
1389  if(n!=cv || !constant_int_p(emc)) {
1390  pc = CHAIN_SWORD(pc, "=");
1391  pc = gen_nconc(pc, words_expression(eme, ppdl));
1392  cv = n;
1393  }
1394  cv++;
1395  first = false;
1396  };
1397  pc = CHAIN_SWORD(pc,"}");
1398  return pc;
1399  }
1400  pips_internal_error("unexpected case");
1401  return NIL;
1402 }
type copy_type(type p)
TYPE.
Definition: ri.c:2655
void free_type(type p)
Definition: ri.c:2658
#define ret(why, what)
true if not a remapping for old.
Definition: dynamic.c:986
#define STRING(x)
Definition: genC.h:87
#define DUMMY_MEMBER_PREFIX
Definition: naming-local.h:90
char * i2a(int)
I2A (Integer TO Ascii) yields a string for a given Integer.
Definition: string.c:121
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define same_string_p(s1, s2)
#define string_undefined
Definition: newgen_types.h:40
#define string_undefined_p(s)
Definition: newgen_types.h:41
static list words_late_qualifiers(list obj)
Definition: declarations.c:805
list words_type(type obj, list *ppdl, bool argument_p)
obj is the type to describe
Definition: declarations.c:821
list words_dimensions(list dims, list *ppdl)
Definition: declarations.c:932
list c_words_entity(type t, list name, list *ppdl)
static list words_initial_qualifiers(list obj)
Definition: declarations.c:800
list words_expression(expression obj, list *ppdl)
This one is exported.
Definition: misc.c:2611
static bool argument_p(entity e)
This function return a bool indicating if related entity e represents an argument.
list lparams
Array bounds.
Definition: reindexing.c:111
bool array_type_p(type)
Definition: type.c:2942
bool qualifiers_restrict_p(list)
Check that a qualifier list contains the restrict qualifier.
Definition: type.c:5466
bool qualifiers_const_p(list)
Check that a qualifier list contains the const qualifier.
Definition: type.c:5453
bool overloaded_parameters_p(list)
Definition: type.c:5236
bool basic_type_p(type)
Safer than the other implementation? bool pointer_type_p(type t) { bool is_pointer = false;.
Definition: type.c:2912
bool pointer_type_p(type)
Check for scalar pointers.
Definition: type.c:2993
bool bit_type_p(type)
Definition: type.c:2843
bool string_type_p(type)
Definition: type.c:2854
bool typedef_type_p(type)
Returns true if t is a typedefED type.
Definition: type.c:3189
#define type_enum_p(x)
Definition: ri.h:2968
#define dummy_identifier(x)
Definition: ri.h:1033
#define basic_pointer(x)
Definition: ri.h:637
#define type_struct_p(x)
Definition: ri.h:2962
#define parameter_dummy(x)
Definition: ri.h:1823
#define parameter_type(x)
Definition: ri.h:1819
#define symbolic_constant(x)
Definition: ri.h:2599
#define constant_int(x)
Definition: ri.h:850
#define type_union_p(x)
Definition: ri.h:2965
#define value_symbolic(x)
Definition: ri.h:3070
#define basic_typedef(x)
Definition: ri.h:643
#define type_undefined_p(x)
Definition: ri.h:2884
#define dummy_unknown_p(x)
Definition: ri.h:1028
#define type_void(x)
Definition: ri.h:2961
#define constant_int_p(x)
Definition: ri.h:848
#define type_void_p(x)
Definition: ri.h:2959
#define functional_parameters(x)
Definition: ri.h:1442
#define PARAMETER(x)
PARAMETER.
Definition: ri.h:1788
#define basic_bit(x)
Definition: ri.h:634
#define type_varargs_p(x)
Definition: ri.h:2953
#define variable_dimensions(x)
Definition: ri.h:3122
#define symbolic_expression(x)
Definition: ri.h:2597
#define entity_initial(x)
Definition: ri.h:2796

References argument_p(), array_type_p(), basic_bit, basic_derived, basic_pointer, basic_type_p(), basic_typedef, bit_type_p(), c_words_entity(), CAR, CDR, CHAIN_SWORD, concatenate(), CONS, constant_int, constant_int_p, copy_type(), declarable_type_p(), derived_type_p(), DUMMY_ENUM_PREFIX, dummy_identifier, DUMMY_MEMBER_PREFIX, DUMMY_STRUCT_PREFIX, DUMMY_UNION_PREFIX, dummy_unknown_p, ENDP, ENTITY, entity_initial, entity_local_name(), entity_name, entity_type, entity_user_name(), ENUM_PREFIX, f(), free(), free_type(), functional_parameters, functional_result, gen_full_free_list(), gen_in_list_p(), gen_length(), gen_nconc(), gen_once(), get_bool_property(), i2a(), list_to_string(), list_undefined, lparams, NIL, overloaded_parameters_p(), PARAMETER, parameter_dummy, parameter_type, pips_debug, pips_internal_error, pointer_type_p(), POP, qualifiers_const_p(), qualifiers_restrict_p(), ret, same_string_p, strdup(), STRING, string_type_p(), string_undefined, string_undefined_p, STRUCT_PREFIX, symbolic_constant, symbolic_expression, type_enum, type_enum_p, type_functional, type_functional_p, type_struct, type_struct_p, type_undefined_p, type_union, type_union_p, type_varargs_p, type_variable, type_variable_p, type_void, type_void_p, typedef_type_p(), UNION_PREFIX, value_symbolic, variable_basic, variable_dimensions, variable_qualifiers, words_dimensions(), words_expression(), words_initial_qualifiers(), words_late_qualifiers(), words_qualifiers(), and words_type().

Referenced by c_words_simplified_entity(), and generic_c_words_entity().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ generic_words_qualifiers()

static list generic_words_qualifiers ( list  obj,
bool  initial_p,
bool  late_p 
)
static

================C prettyprinter functions=================

returns a list of words corresponding to a list of qualifiers...

obj is a list of qualifiers.

initial_p :

late_p:

Space management?

FI: might not be an initial qualifier either

FI: the auto case was missing; I have no idea why.

asm qualifiers a reprinted in the end ...

FI: I have no idea about initial_p and late_p...

Definition at line 704 of file declarations.c.

705 {
706  list pc = NIL;
707  FOREACH(QUALIFIER, q, obj) {
708  switch (qualifier_tag(q)) {
710  if(initial_p)
711  pc = CHAIN_SWORD(pc, "register ");
712  break;
713  case is_qualifier_thread:
714  if(initial_p)
715  pc = CHAIN_SWORD(pc, "__thread ");
716  break;
717  case is_qualifier_const:
718  if(late_p)
719  pc = CHAIN_SWORD(pc, "const ");
720  break;
722  /* FI: might not be an initial qualifier either */
723  if(late_p)
724  pc = CHAIN_SWORD(pc, "restrict ");
725  break;
727  if(initial_p)
728  pc = CHAIN_SWORD(pc, "volatile ");
729  break;
730  case is_qualifier_auto:
731  /* FI: the auto case was missing; I have no idea why. */
732  if(initial_p)
733  pc = CHAIN_SWORD(pc, "auto ");
734  break;
735  case is_qualifier_asm: {
736  /* asm qualifiers a reprinted in the end ... */
737  } break;
739  /* FI: I have no idea about initial_p and late_p... */
740  if (initial_p)
741  pc = CHAIN_SWORD(pc,"static ");
742  break;
743  case is_qualifier_local:
744  {
745  const char * q = get_string_property("PRETTYPRINT_LOCAL_QUALIFIER");
746  if (! same_string_p(q, ""))
747  {
748  pc = CHAIN_SWORD(pc, q);
749  pc = CHAIN_SWORD(pc, " ");
750  }
751  break;
752  }
753  case is_qualifier_global:
754  {
755  const char * q = get_string_property("PRETTYPRINT_GLOBAL_QUALIFIER");
756  if (! same_string_p(q, ""))
757  {
758  pc = CHAIN_SWORD(pc, q);
759  pc = CHAIN_SWORD(pc, " ");
760  }
761  break;
762  }
764  {
765  const char * q = get_string_property("PRETTYPRINT_CONSTANT_QUALIFIER");
766  if (! same_string_p(q, ""))
767  {
768  pc = CHAIN_SWORD(pc, q);
769  pc = CHAIN_SWORD(pc, " ");
770  }
771  break;
772  }
774  {
775  const char * q = get_string_property("PRETTYPRINT_PRIVATE_QUALIFIER");
776  if (! same_string_p(q, ""))
777  {
778  pc = CHAIN_SWORD(pc, q);
779  pc = CHAIN_SWORD(pc, " ");
780  }
781  break;
782  }
783  default:
784  pips_internal_error("Unexpected qualifier tag.\n");
785  }
786  }
787 
788  if(!initial_p && late_p && !ENDP(pc))
789  pc = gen_nconc(CHAIN_SWORD(NIL, " "), pc);
790 
791  return pc;
792 }
char * get_string_property(const char *)
#define qualifier_tag(x)
Definition: ri.h:2175
@ is_qualifier_volatile
Definition: ri.h:2129
@ is_qualifier_register
Definition: ri.h:2130
@ is_qualifier_constant
Definition: ri.h:2137
@ is_qualifier_restrict
Definition: ri.h:2128
@ is_qualifier_thread
Definition: ri.h:2132
@ is_qualifier_local
Definition: ri.h:2135
@ is_qualifier_const
Definition: ri.h:2127
@ is_qualifier_static_dimension
Definition: ri.h:2134
@ is_qualifier_auto
Definition: ri.h:2131
@ is_qualifier_private
Definition: ri.h:2138
@ is_qualifier_asm
Definition: ri.h:2133
@ is_qualifier_global
Definition: ri.h:2136

References CHAIN_SWORD, ENDP, FOREACH, gen_nconc(), get_string_property(), is_qualifier_asm, is_qualifier_auto, is_qualifier_const, is_qualifier_constant, is_qualifier_global, is_qualifier_local, is_qualifier_private, is_qualifier_register, is_qualifier_restrict, is_qualifier_static_dimension, is_qualifier_thread, is_qualifier_volatile, NIL, pips_internal_error, QUALIFIER, qualifier_tag, and same_string_p.

Referenced by words_initial_qualifiers(), words_late_qualifiers(), and words_qualifiers().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ safe_c_words_entity()

list safe_c_words_entity ( type  t,
list  name 
)

Ignore the parser declared entities?

Parameters
nameame

Definition at line 1433 of file declarations.c.

1434 {
1435  /* Ignore the parser declared entities? */
1436  list pdl = NIL;
1437  list l = generic_c_words_entity(t, name, true, false, &pdl);
1438  gen_free_list(pdl);
1439  return l;
1440 }

References gen_free_list(), generic_c_words_entity(), and NIL.

Referenced by FindOrCreateCurrentEntity(), UpdateEntity(), and UpdateFunctionEntity().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sentence_head()

sentence sentence_head ( entity  e,
list ppdl 
)

We have no way to distinguish between the SUBROUTINE and PROGRAM They two have almost the same properties.

For the time being, especially for the PUMA project, we have a temporary idea to deal with it: When there's no argument(s), it should be a PROGRAM, otherwise, it should be a SUBROUTINE. Lei ZHOU 18/10/91

correct PROGRAM and SUBROUTINE distinction added, FC 18/08/94 approximate BLOCK DATA / SUBROUTINE distinction also added. FC 09/97

Parameters
ppdlpdl

Definition at line 601 of file declarations.c.

602 {
603  list pc = NIL;
604  type te = entity_type(e);
605  functional fe;
606  type tr;
607  list args = words_parameters(e, ppdl);
608 
609  pips_assert("is functionnal", type_functional_p(te));
610 
611  if (static_module_p(e))
612  pc = CHAIN_SWORD(pc,"static ");
613 
614  fe = type_functional(te);
615  tr = functional_result(fe);
616 
617  switch(type_tag(tr)) {
618  case is_type_void:
619  switch(get_prettyprint_language_tag()) {
620  case is_language_fortran:
622  if (entity_main_module_p(e))
623  pc = CHAIN_SWORD(pc,"PROGRAM ");
624  else {
625  if (entity_blockdata_p(e))
626  pc = CHAIN_SWORD(pc, "BLOCKDATA ");
627  else if (entity_f95module_p(e))
628  pc = CHAIN_SWORD(pc, "MODULE ");
629  else
630  pc = CHAIN_SWORD(pc,"SUBROUTINE ");
631  }
632  break;
633  case is_language_c:
634  pc = CHAIN_SWORD(pc,"void ");
635  break;
636  default:
637  pips_internal_error("Language unknown !");
638  break;
639  }
640  break;
641  case is_type_variable: {
642  list pdl = NIL;
643  // FI: the qualifiers are dropped...
644  variable var = type_variable(tr);
645  basic b = variable_basic(var);
646  list ql = variable_qualifiers(var);
647  pc = gen_nconc(pc, words_basic(b, &pdl));
648  pc = gen_nconc(words_qualifiers(ql), pc);
649  switch(get_prettyprint_language_tag()) {
650  case is_language_fortran:
652  pc = CHAIN_SWORD(pc," FUNCTION ");
653  break;
654  case is_language_c:
655  pc = CHAIN_SWORD(pc," ");
656  break;
657  default:
658  pips_internal_error("Language unknown !");
659  break;
660  }
661  break;
662  }
663  case is_type_unknown:
664  /*
665  * For C functions with no return type.
666  * It can be treated as of type int, but we keep it unknown
667  * for the moment, to make the differences and to regenerate initial code
668  */
669  break;
670  default:
671  pips_internal_error("unexpected type for result");
672  }
673 
674  pc = CHAIN_SWORD(pc, entity_user_name(e));
675 
676  if (!ENDP(args)) {
677  pc = CHAIN_SWORD(pc, "(");
678  pc = gen_nconc(pc, args);
679  pc = CHAIN_SWORD(pc, ")");
680  } else if (type_variable_p(tr)
682  && (type_unknown_p(tr) || type_void_p(tr)))) {
683  pc = CHAIN_SWORD(pc, "()");
684  }
685 
687  0,
688  0,
689  pc)));
690 }
bool prettyprint_language_is_c_p()
Definition: language.c:91
enum language_utype get_prettyprint_language_tag()
Definition: language.c:67
static list words_parameters(entity e, list *ppdl)
Definition: declarations.c:96
list words_basic(basic obj, list *ppdl)
what about simple DOUBLE PRECISION, REAL, INTEGER...
Definition: declarations.c:323
bool entity_main_module_p(entity e)
Definition: entity.c:700
bool entity_blockdata_p(entity e)
Definition: entity.c:712
bool entity_f95module_p(entity e)
Definition: entity.c:707
@ is_language_fortran
Definition: ri.h:1566
@ is_language_fortran95
Definition: ri.h:1568
@ is_language_c
Definition: ri.h:1567

References CHAIN_SWORD, ENDP, entity_blockdata_p(), entity_f95module_p(), entity_main_module_p(), entity_type, entity_user_name(), functional_result, gen_nconc(), get_prettyprint_language_tag(), is_language_c, is_language_fortran, is_language_fortran95, is_sentence_unformatted, is_type_unknown, is_type_variable, is_type_void, make_sentence(), make_unformatted(), NIL, pips_assert, pips_internal_error, prettyprint_language_is_c_p(), static_module_p(), type_functional, type_functional_p, type_tag, type_unknown_p, type_variable, type_variable_p, type_void_p, variable_basic, variable_qualifiers, words_basic(), words_parameters(), and words_qualifiers().

Referenced by ensure_comment_consistency().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Sentence_Variable()

sentence Sentence_Variable ( entity  e)

Definition at line 583 of file declarations.c.

584 {
585  list pdl = NIL;
586  sentence s = sentence_variable(e, &pdl);
587  gen_free_list(pdl);
588  return s;
589 }
sentence sentence_variable(entity e, list *ppdl)
Definition: declarations.c:567

References gen_free_list(), NIL, and sentence_variable().

Referenced by make_emulated_shared_variable(), and set_dimensions_of_local_variable_family().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sentence_variable()

sentence sentence_variable ( entity  e,
list ppdl 
)
Parameters
ppdlpdl

Definition at line 567 of file declarations.c.

568 {
569  list pc = NIL;
570  type te = entity_type(e);
571 
572  pips_assert("is a variable", type_variable_p(te));
573 
574  pc = gen_nconc(pc, words_basic(variable_basic(type_variable(te)), ppdl));
575  pc = CHAIN_SWORD(pc, " ");
576 
577  pc = gen_nconc(pc, words_declaration(e, true, ppdl));
578 
580  make_unformatted(NULL, 0, 0, pc)));
581 }
list words_declaration(entity e, bool prettyprint_common_variable_dimensions_p, list *ppdl)
some compilers don't like dimensions that are declared twice.
Definition: declarations.c:277

References CHAIN_SWORD, entity_type, gen_nconc(), is_sentence_unformatted, make_sentence(), make_unformatted(), NIL, pips_assert, type_variable, type_variable_p, variable_basic, words_basic(), and words_declaration().

Referenced by Sentence_Variable().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ words_basic()

list words_basic ( basic  obj,
list ppdl 
)

what about simple DOUBLE PRECISION, REAL, INTEGER...

This may happen in debugging statements

if(basic_int(obj)==4) { pc = CHAIN_SWORD(pc,"INTEGER"); } else {

FI: Use "bool" of stdbool.h instead of "int" but it leads to include issue for generated code; avoid stdbool.h and use "_Bool" directly but it leads to infinite loop from "_Bool" to "_Bool" because "_Bool" is declared as a typedef in anr999

should be a user error? Or simply bootstrap.c is not accurate?

ignore if it is signed or unsigned

The following code maybe redundant, because of tests in c_words_entity

This may occur in the parser when a variable is used before it is fully defined (see ptr in decl42.c)

FI: This space may not be always useful

Parameters
objbj
ppdlpdl

Definition at line 323 of file declarations.c.

324 {
325  list pc = NIL;
326 
327  if ( basic_undefined_p(obj) ) {
328  /* This may happen in debugging statements */
329  pc = CHAIN_SWORD(pc,"undefined");
330  } else {
331  switch ( basic_tag(obj) ) {
332  case is_basic_int: {
333  switch(get_prettyprint_language_tag()) {
334  case is_language_fortran:
336 /* if(basic_int(obj)==4) {
337  pc = CHAIN_SWORD(pc,"INTEGER");
338  } else { */
339  pc = CHAIN_SWORD(pc,"INTEGER*");
340  pc = CHAIN_IWORD(pc,basic_int(obj));
341 // }
342  break;
343  case is_language_c:
344  {
345  string pn;
346  switch (basic_int(obj)) {
347  // FC: if the numbering was nice, it could use an array...
348  case 1: pn = "PRETTYPRINT_C_CHAR_TYPE";
349  break;
350  case 2: pn = "PRETTYPRINT_C_SHORT_TYPE";
351  break;
352  case 4: pn = "PRETTYPRINT_C_INT_TYPE";
353  break;
354  case 6: pn = "PRETTYPRINT_C_LONG_TYPE";
355  break;
356  case 8: pn = "PRETTYPRINT_C_LONGLONG_TYPE";
357  break;
358  case 9: pn = "PRETTYPRINT_C_INT128_TYPE";
359  break;
360  case 11: pn = "PRETTYPRINT_C_UCHAR_TYPE";
361  break;
362  case 12: pn = "PRETTYPRINT_C_USHORT_TYPE";
363  break;
364  case 14: pn = "PRETTYPRINT_C_UINT_TYPE";
365  break;
366  case 16: pn = "PRETTYPRINT_C_ULONG_TYPE";
367  break;
368  case 18: pn = "PRETTYPRINT_C_ULONGLONG_TYPE";
369  break;
370  case 19: pn = "PRETTYPRINT_C_UINT128_TYPE";
371  break;
372  case 21: pn = "PRETTYPRINT_C_SCHAR_TYPE";
373  break;
374  case 22: pn = "PRETTYPRINT_C_SSHORT_TYPE";
375  break;
376  case 24: pn = "PRETTYPRINT_C_SINT_TYPE";
377  break;
378  case 26: pn = "PRETTYPRINT_C_SLONG_TYPE";
379  break;
380  case 28: pn = "PRETTYPRINT_C_SLONGLONG_TYPE";
381  break;
382  default:
383  pips_internal_error("Unexpected int number %d\n", basic_int(obj));
384  }
385  pc = CHAIN_SWORD(pc, get_string_property(pn));
386  break;
387  }
388  default:
389  pips_internal_error("Language unknown !");
390  break;
391  }
392  break;
393  }
394  case is_basic_float: {
395  switch(get_prettyprint_language_tag()) {
396  case is_language_fortran:
398  pc = CHAIN_SWORD(pc,"REAL*");
399  pc = CHAIN_IWORD(pc,basic_float(obj));
400  break;
401  case is_language_c:
402  switch ( basic_float(obj) ) {
403  case 4:
404  pc = CHAIN_SWORD(pc,"float");
405  break;
406  case 8:
407  pc = CHAIN_SWORD(pc,"double");
408  break;
409  case 16:
410  pc = CHAIN_SWORD(pc,"long double");
411  break;
412  }
413  break;
414  default:
415  pips_internal_error("Language unknown !");
416  break;
417  }
418  break;
419  }
420  case is_basic_logical: {
421  switch(get_prettyprint_language_tag()) {
422  case is_language_fortran:
423  pc = CHAIN_SWORD(pc,"LOGICAL*");
424  pc = CHAIN_IWORD(pc,basic_logical(obj));
425  break;
426  case is_language_c:
427  pc = CHAIN_SWORD(pc,"int"); /* FI: Use "bool" of stdbool.h instead
428  of "int" but it leads to
429  include issue for
430  generated code; avoid stdbool.h
431  and use "_Bool" directly
432  but it leads to infinite
433  loop from "_Bool" to
434  "_Bool" because "_Bool"
435  is declared as a typedef
436  in anr999 */
437  break;
439  pips_internal_error("Need to update F95 case");
440  break;
441  default:
442  pips_internal_error("Language unknown !");
443  break;
444  }
445  break;
446  }
447  case is_basic_overloaded: {
448  /* should be a user error? Or simply bootstrap.c is not accurate? */
449  switch(get_prettyprint_language_tag()) {
450  case is_language_fortran:
451  pc = CHAIN_SWORD(pc,"OVERLOADED");
452  break;
453  case is_language_c:
454  pc = CHAIN_SWORD(pc,"overloaded");
455  break;
457  pips_internal_error("Need to update F95 case");
458  break;
459  default:
460  pips_internal_error("Language unknown !");
461  break;
462  }
463  break;
464  }
465  case is_basic_complex: {
466  switch(get_prettyprint_language_tag()) {
467  case is_language_fortran:
469  pc = CHAIN_SWORD(pc,"COMPLEX*");
470  pc = CHAIN_IWORD(pc,basic_complex(obj));
471  break;
472  case is_language_c:
473  switch ( basic_complex(obj) ) {
474  case 8:
475  pc = CHAIN_SWORD(pc,"_Complex");
476  break;
477  case 9:
478  pc = CHAIN_SWORD(pc,"float _Complex");
479  break;
480  case 16:
481  pc = CHAIN_SWORD(pc,"double _Complex");
482  break;
483  case 32:
484  pc = CHAIN_SWORD(pc,"long double _Complex");
485  break;
486  default:
487  pips_internal_error("Unexpected complex size");
488  }
489  break;
490  default:
491  pips_internal_error("Language unknown !");
492  break;
493  }
494  break;
495  }
496  case is_basic_string: {
497  switch(get_prettyprint_language_tag()) {
498  case is_language_fortran:
499  pc = CHAIN_SWORD(pc,"CHARACTER*");
500  pc = gen_nconc( pc, words_value( basic_string(obj) ) );
501  break;
502  case is_language_c:
503  pc = CHAIN_SWORD(pc,"char *"); // FI: should it be char[]?
504  break;
506  pips_internal_error("Need to update F95 case");
507  break;
508  default:
509  pips_internal_error("Language unknown !");
510  break;
511  }
512  break;
513  }
514  case is_basic_bit: {
515  symbolic bs = basic_bit(obj);
516  int i = constant_int(symbolic_constant(bs));
517  pips_debug(7,"Bit field basic: %d\n",i);
518  pc = CHAIN_SWORD(pc,"int"); /* ignore if it is signed or unsigned */
519  break;
520  }
521  /* The following code maybe redundant, because of tests in c_words_entity*/
522  case is_basic_pointer: {
523  type t = basic_pointer(obj);
524  pips_debug(7,"Basic pointer\n");
525  if ( type_undefined_p(t) ) {
526  /* This may occur in the parser when a variable is used
527  before it is fully defined (see ptr in decl42.c) */
528  pc = CHAIN_SWORD(pc,"type_undefined *");
529  } else {
530  pc = gen_nconc( pc, words_type( t, ppdl, false ) );
531  pc = CHAIN_SWORD(pc," *");
532  }
533  break;
534  }
535  case is_basic_derived: {
536  entity ent = basic_derived(obj);
537  const char* name = entity_user_name( ent );
538  const char* lname = entity_local_name( ent );
539  type t = entity_type(ent);
540 
541  if ( strstr( lname, STRUCT_PREFIX DUMMY_STRUCT_PREFIX ) == NULL
542  && strstr( lname, UNION_PREFIX DUMMY_UNION_PREFIX ) == NULL
543  && strstr( lname, ENUM_PREFIX DUMMY_ENUM_PREFIX ) == NULL ) {
544  pc = gen_nconc( pc, words_type( t, ppdl, false ) );
545  pc = CHAIN_SWORD(pc," ");
546  pc = CHAIN_SWORD(pc,name);
547  pc = CHAIN_SWORD(pc," "); /* FI: This space may not be always useful */
548  } else {
549  pc = gen_nconc( pc, c_words_entity( t, NIL, ppdl ) );
550  }
551  break;
552  }
553  case is_basic_typedef: {
554  entity ent = basic_typedef(obj);
555  pc = CHAIN_SWORD(pc,entity_user_name(ent));
556  break;
557  }
558  default:
559  pips_internal_error("unexpected basic tag %d", basic_tag(obj));
560  }
561  }
562  return(pc);
563 }
static list words_value(value obj)
Definition: declarations.c:74
@ is_basic_derived
Definition: ri.h:579
@ is_basic_string
Definition: ri.h:576
@ is_basic_float
Definition: ri.h:572
@ is_basic_bit
Definition: ri.h:577
@ is_basic_pointer
Definition: ri.h:578
@ is_basic_overloaded
Definition: ri.h:574
@ is_basic_int
Definition: ri.h:571
@ is_basic_logical
Definition: ri.h:573
@ is_basic_typedef
Definition: ri.h:580
@ is_basic_complex
Definition: ri.h:575
#define basic_int(x)
Definition: ri.h:616
#define basic_tag(x)
Definition: ri.h:613
#define basic_undefined_p(x)
Definition: ri.h:557
#define basic_logical(x)
Definition: ri.h:622
#define basic_float(x)
Definition: ri.h:619
#define basic_complex(x)
Definition: ri.h:628
#define basic_string(x)
Definition: ri.h:631
#define CHAIN_IWORD(l, i)

References basic_bit, basic_complex, basic_derived, basic_float, basic_int, basic_logical, basic_pointer, basic_string, basic_tag, basic_typedef, basic_undefined_p, c_words_entity(), CHAIN_IWORD, CHAIN_SWORD, constant_int, DUMMY_ENUM_PREFIX, DUMMY_STRUCT_PREFIX, DUMMY_UNION_PREFIX, entity_local_name(), entity_type, entity_user_name(), ENUM_PREFIX, gen_nconc(), get_prettyprint_language_tag(), get_string_property(), is_basic_bit, is_basic_complex, is_basic_derived, is_basic_float, is_basic_int, is_basic_logical, is_basic_overloaded, is_basic_pointer, is_basic_string, is_basic_typedef, is_language_c, is_language_fortran, is_language_fortran95, lname(), NIL, pips_debug, pips_internal_error, STRUCT_PREFIX, symbolic_constant, type_undefined_p, UNION_PREFIX, words_type(), and words_value().

Referenced by basic_to_string(), find_or_create_allocatable_struct(), sentence_head(), sentence_variable(), and words_type().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ words_brace_expression()

list words_brace_expression ( expression  exp,
list ppdl 
)
Parameters
expxp
ppdlpdl

Definition at line 910 of file declarations.c.

911 {
912  list pc = NIL;
914  bool first = true;
915  bool space_p = get_bool_property("PRETTYPRINT_LISTS_WITH_SPACES");
916 
917  pc = CHAIN_SWORD(pc,"{");
918  MAP(EXPRESSION,e,
919  {
920  if (!first)
921  pc = CHAIN_SWORD(pc, space_p? ", " : ",");
922  if (c_brace_expression_p(e))
923  pc = gen_nconc(pc,words_brace_expression(e, ppdl));
924  else
925  pc = gen_nconc(pc,words_expression(e, ppdl));
926  first = false;
927  },args);
928  pc = CHAIN_SWORD(pc,"}");
929  return pc;
930 }
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
list words_brace_expression(expression exp, list *ppdl)
Definition: declarations.c:910
bool c_brace_expression_p(expression e)
Definition: declarations.c:898
#define call_arguments(x)
Definition: ri.h:711
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207

References c_brace_expression_p(), call_arguments, CHAIN_SWORD, exp, EXPRESSION, expression_syntax, gen_nconc(), get_bool_property(), MAP, NIL, syntax_call, and words_expression().

Referenced by words_brace_op(), and words_variable_or_function().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ words_constant()

static list words_constant ( constant  obj)
static

hat about real, double, string constants ... ?

Definition at line 60 of file declarations.c.

61 {
62  list pc=NIL;
63 
64  if (constant_int_p(obj)) {
65  pc = CHAIN_IWORD(pc,constant_int(obj));
66  }
67  else {
68  pips_internal_error("unexpected tag");
69  }
70  /*What about real, double, string constants ... ?*/
71  return(pc);
72 }

References CHAIN_IWORD, constant_int, constant_int_p, NIL, and pips_internal_error.

Referenced by words_value().

+ Here is the caller graph for this function:

◆ words_declaration()

list words_declaration ( entity  e,
bool  prettyprint_common_variable_dimensions_p,
list ppdl 
)

some compilers don't like dimensions that are declared twice.

declarations.c

this is the case of g77 used after hpfc. thus I added a flag not to prettyprint again the dimensions of common variables. FC.

It is in the standard that dimensions cannot be declared twice in a single module. BC.

Parameters
prettyprint_common_variable_dimensions_prettyprint_common_variable_dimensions_p
ppdlpdl

Definition at line 277 of file declarations.c.

279  {
280  list pl = NIL;
281  bool space_p = get_bool_property("PRETTYPRINT_LISTS_WITH_SPACES");
282 
284 
285  if (type_variable_p(entity_type(e))) {
286  if (prettyprint_common_variable_dimensions_p || !(variable_in_common_p(e)
287  || variable_static_p(e))) {
290 
291  switch(get_prettyprint_language_tag()) {
292  case is_language_fortran:
294  pl = CHAIN_SWORD(pl, "(");
295  MAPL(pd,
296  {
297  pl = gen_nconc(pl, words_dimension(DIMENSION(CAR(pd)), ppdl));
298  if (CDR(pd) != NIL) pl = CHAIN_SWORD(pl, space_p? ", " : ",");
299  }, dims)
300  ;
301  pl = CHAIN_SWORD(pl, ")");
302  break;
303  case is_language_c:
304  MAPL(pd,
305  {
306  pl = CHAIN_SWORD(pl, "[");
307  pl = gen_nconc(pl, words_dimension(DIMENSION(CAR(pd)), ppdl));
308  pl = CHAIN_SWORD(pl, "]");
309  }, dims)
310  ;
311  break;
312  default:
313  pips_internal_error("Language unknown !");
314  }
315  }
316  }
317  }
319  return (pl);
320 }
void attach_declaration_to_words(list l, entity e)
Attach a declaration to all the words of the given list:
#define MAPL(_map_list_cp, _code, _l)
Apply some code on the addresses of all the elements of a list.
Definition: newgen_list.h:203
static list words_dimension(dimension obj, list *ppdl)
Definition: declarations.c:189
static hash_table pl
properties are stored in this hash table (string -> property) for fast accesses.
Definition: properties.c:783
bool variable_in_common_p(entity)
true if v is in a common.
Definition: variable.c:1570
bool variable_static_p(entity)
true if v appears in a SAVE statement, or in a DATA statement, or is declared static i C.
Definition: variable.c:1579

References attach_declaration_to_words(), CAR, CDR, CHAIN_SWORD, DIMENSION, entity_type, entity_user_name(), gen_nconc(), get_bool_property(), get_prettyprint_language_tag(), is_language_c, is_language_fortran, is_language_fortran95, MAPL, NIL, pips_internal_error, pl, type_variable, type_variable_p, variable_dimensions, variable_in_common_p(), variable_static_p(), and words_dimension().

Referenced by loop_private_variables(), sentence_area(), sentence_variable(), and text_entity_declaration().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ words_dimension()

static list words_dimension ( dimension  obj,
list ppdl 
)
static

The lower bound of array in C is always equal to 0, we only need to print (upper dimension + 1)

To deal with partial eval generated expressions

to be refined here to make more beautiful expression, use normalize ? FI: why would we modify the user C source code?

Definition at line 189 of file declarations.c.

190 {
191  list pc = NIL;
192  call c = call_undefined;
197  intptr_t up, i;
199  {
201  // Not asterisk for unbound dimension in F95
202  if(unbounded_dimension_p(obj)) {
203  pc = CHAIN_SWORD(pc,":");
204  break;
205  }
206  // paste code to avoid fall-through warnings
207  pc = words_expression( dimension_lower(obj), ppdl );
208  pc = CHAIN_SWORD(pc,":");
209  pc = gen_nconc( pc, words_expression( dimension_upper(obj), ppdl ) );
210  break;
211  case is_language_fortran:
212  pc = words_expression( dimension_lower(obj), ppdl );
213  pc = CHAIN_SWORD(pc,":");
214  pc = gen_nconc( pc, words_expression( dimension_upper(obj), ppdl ) );
215  break;
216  case is_language_c:
217  /* The lower bound of array in C is always equal to 0,
218  we only need to print (upper dimension + 1) */
219  if ( unbounded_dimension_p( obj ) )
220  pc = CHAIN_SWORD(pc,"");
221  else {
222  eup = dimension_upper(obj);
223  if ( false && expression_integer_value( eup, &up ) ) {
224  /*
225  * FI: why do you want to change the source code? Because it may no
226  * longer be the user source code after partial evaluation
227  */
228  pc = CHAIN_IWORD(pc,up+1);
229  }
230  if ( expression_constant_p( eup )
232  /* To deal with partial eval generated expressions */
233  up = expression_to_int( eup );
234  pc = CHAIN_IWORD(pc,up+1);
235  } else {
236  list ql = dimension_qualifiers(obj);
237  list qpc = words_qualifiers(ql);
238  if ( expression_call_p( eup ) ) {
239  c = syntax_call(expression_syntax(eup));
240  f = call_function(c);
241  if ( ENTITY_MINUS_P(f) || ENTITY_MINUS_C_P(f) ) {
242  e1 = binary_call_lhs(c);
243  e2 = binary_call_rhs(c);
244  if ( expression_integer_value( e2, &i ) && i == 1 )
245  pc = words_expression( e1, ppdl );
246  }
247  }
248  if ( pc == NIL ) {
249  /* to be refined here to make more beautiful expression,
250  * use normalize ? FI: why would we modify the user C source code?
251  */
253  eup,
254  int_to_expression( 1 ) ),
255  ppdl );
256  }
257  if(!ENDP(qpc))
258  pc = gen_nconc(qpc, pc);
259  }
260  }
261  break;
262  default:
263  pips_internal_error("Language tag=%d unknown.\n",
265  break;
266  }
267  return pc;
268 }
bool expression_constant_p(expression)
HPFC module by Fabien COELHO.
Definition: expression.c:2453
#define binary_call_rhs(c)
#define ENTITY_MINUS_P(e)
#define ENTITY_MINUS_C_P(e)
#define binary_call_lhs(c)
entity CreateIntrinsic(string name)
this function does not create an intrinsic function because they must all be created beforehand by th...
Definition: entity.c:1311
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
int expression_to_int(expression exp)
================================================================
Definition: expression.c:2205
constant expression_constant(expression exp)
This function returns a "constant" object if the expression is a constant such as 10,...
Definition: expression.c:2347
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
bool unbounded_dimension_p(dimension dim)
bool unbounded_dimension_p(dim) input : a dimension of an array entity.
Definition: expression.c:1130
#define dimension_lower(x)
Definition: ri.h:980
#define entity_undefined
Definition: ri.h:2761
#define expression_undefined
Definition: ri.h:1223
#define dimension_upper(x)
Definition: ri.h:982
#define dimension_qualifiers(x)
Definition: ri.h:984
#define call_undefined
Definition: ri.h:685
#define intptr_t
Definition: stdint.in.h:294

References binary_call_lhs, binary_call_rhs, call_function, call_undefined, CHAIN_IWORD, CHAIN_SWORD, constant_int_p, CreateIntrinsic(), dimension_lower, dimension_qualifiers, dimension_upper, ENDP, ENTITY_MINUS_C_P, ENTITY_MINUS_P, entity_undefined, expression_call_p(), expression_constant(), expression_constant_p(), expression_integer_value(), expression_syntax, expression_to_int(), expression_undefined, f(), gen_nconc(), get_prettyprint_language_tag(), int_to_expression(), intptr_t, is_language_c, is_language_fortran, is_language_fortran95, MakeBinaryCall(), NIL, pips_internal_error, syntax_call, unbounded_dimension_p(), words_expression(), and words_qualifiers().

Referenced by words_declaration(), and words_dimensions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ words_dimensions()

list words_dimensions ( list  dims,
list ppdl 
)
Parameters
dimsims
ppdlpdl

Definition at line 932 of file declarations.c.

933 {
934  list pc = NIL;
935  bool space_p = get_bool_property("PRETTYPRINT_LISTS_WITH_SPACES");
936 
937  switch(get_prettyprint_language_tag()) {
938  case is_language_fortran:
939  case is_language_fortran95: {
940  pc = CHAIN_SWORD(pc, "(");
941  string spacer = "";
942  FOREACH(dimension,d,dims) {
943  pc = CHAIN_SWORD(pc, spacer);
944  pc = gen_nconc(pc, words_dimension(d, ppdl));
945  spacer = space_p ? ", " : ",";
946  }
947  pc = CHAIN_SWORD(pc, ")");
948  break;
949  }
950  case is_language_c: {
951  FOREACH(dimension,d,dims) {
952  pc = CHAIN_SWORD(pc, "[");
953  pc = gen_nconc(pc, words_dimension(d, ppdl));
954  pc = CHAIN_SWORD(pc, "]");
955  }
956  break;
957  }
958  default:
959  pips_internal_error("Language unknown !");
960  break;
961  }
962  return pc;
963 }

References CHAIN_SWORD, FOREACH, gen_nconc(), get_bool_property(), get_prettyprint_language_tag(), is_language_c, is_language_fortran, is_language_fortran95, NIL, pips_internal_error, and words_dimension().

Referenced by generic_c_words_simplified_entity(), get_symbol_table(), and words_type().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ words_enum()

static list words_enum ( const char *  name1,
list  l,
bool  space_p,
list  pc,
list ppdl 
)
static

Definition at line 1535 of file declarations.c.

1536 {
1537  bool first = true;
1538  pc = CHAIN_SWORD(pc,"enum ");
1539  if(strstr(name1,DUMMY_ENUM_PREFIX)==NULL) {
1540  pc = CHAIN_SWORD(pc,name1);
1541  pc = CHAIN_SWORD(pc," ");
1542  }
1543  pc = CHAIN_SWORD(pc,"{");
1544  list cl = list_undefined;
1545  int cv = 0;
1546 
1547  for(cl = l; !ENDP(cl); POP(cl)) {
1548  entity em = ENTITY(CAR(cl));
1549  value emv = entity_initial(em);
1550  symbolic ems = value_symbolic(emv);
1551  expression eme = symbolic_expression(ems);
1553  int n = constant_int(emc);
1554 
1555  // SG has decided not to evaluate expressions containins a sizeof
1556  // operator because the result is architecture dependent and
1557  // because the PIPS user has not specified which architecture
1558  // should be used.
1559  //
1560  // Serge has no idea how many things he has broken in PIPS!!!
1561  // constant integer expressions are used in many declarations and
1562  // expected by PIPS components. Unexpected results are going to
1563  // occur as the blind interpretation of an unknown constant
1564  // returns 0!
1565  //
1566  //if(!constant_int_p(emc))
1567  // pips_internal_error("constant expression not evaluated by parser");
1568 
1569  if (!first)
1570  pc = CHAIN_SWORD(pc, space_p? ", " : ",");
1571  pc = CHAIN_SWORD(pc, entity_user_name(em));
1572  if(n!=cv || !constant_int_p(emc)) {
1573  pc = CHAIN_SWORD(pc, "=");
1574  pc = gen_nconc(pc, words_expression(eme, ppdl));
1575  cv = n;
1576  }
1577  cv++;
1578  first = false;
1579  };
1580  pc = CHAIN_SWORD(pc,"}");
1581  return pc;
1582 }

References CAR, CHAIN_SWORD, constant_int, constant_int_p, DUMMY_ENUM_PREFIX, ENDP, ENTITY, entity_initial, entity_user_name(), gen_nconc(), list_undefined, POP, symbolic_constant, symbolic_expression, value_symbolic, and words_expression().

Referenced by c_text_related_entities().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ words_enum_reference()

static list words_enum_reference ( const char *  name1,
list  pc,
bool  init_p 
)
static

Prolog to print out a struct definition, such as "struct s { int a; int b;}"; for the time being, only the previous function is used.

Definition at line 1524 of file declarations.c.

1525 {
1526  pc = CHAIN_SWORD(pc,"enum ");
1527  if(strstr(name1,DUMMY_ENUM_PREFIX)==NULL) {
1528  pc = CHAIN_SWORD(pc,name1);
1529  if(init_p)
1530  pc = CHAIN_SWORD(pc," ");
1531  }
1532  return pc;
1533 }

References CHAIN_SWORD, and DUMMY_ENUM_PREFIX.

Referenced by c_text_related_entities().

+ Here is the caller graph for this function:

◆ words_initial_qualifiers()

static list words_initial_qualifiers ( list  obj)
static

Definition at line 800 of file declarations.c.

801 {
802  return generic_words_qualifiers(obj, true, false);
803 }
static list generic_words_qualifiers(list obj, bool initial_p, bool late_p)
================C prettyprinter functions=================
Definition: declarations.c:704

References generic_words_qualifiers().

Referenced by generic_c_words_simplified_entity().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ words_late_qualifiers()

static list words_late_qualifiers ( list  obj)
static

Definition at line 805 of file declarations.c.

806 {
807  return generic_words_qualifiers(obj, false, true);
808 }

References generic_words_qualifiers().

Referenced by generic_c_words_simplified_entity().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ words_parameters()

static list words_parameters ( entity  e,
list ppdl 
)
static

If prettyprint alternate returns... Property to be added.

param can be undefined for C language: void foo(void) We do not have an entity corresponding to the 1st argument

Should be correct, but seems useless

FI: types and derived entities used for the formal parameters should be defined before end. If ever they are defined in the formal scope, they cannot be used elsewhere.

FI: It might be better to implement the same behavior without building npdl, by passing an extra parameter... But you would have to check all call sites to c_words_entity().

npdl

Definition at line 96 of file declarations.c.

97 {
98  list pc = NIL;
99  type te = entity_type(e);
100  functional fe;
101  int nparams, i;
102  bool space_p = get_bool_property("PRETTYPRINT_LISTS_WITH_SPACES");
103 
104  pips_assert("is functionnal", type_functional_p(te));
105 
106  fe = type_functional(te);
107  nparams = gen_length(functional_parameters(fe));
108 
109  for (i = 1; i <= nparams; i++) {
111  if (pc != NIL) {
112  pc = CHAIN_SWORD(pc, space_p? ", " : ",");
113  }
114 
115  /* If prettyprint alternate returns... Property to be added. */
116  if ( get_bool_property( "PRETTYPRINT_REGENERATE_ALTERNATE_RETURNS" )
118  pc = CHAIN_SWORD(pc, "*");
119  } else if ( entity_undefined_p(param) ) {
121  type t = parameter_type(p);
122  switch(get_prettyprint_language_tag()) {
123  case is_language_fortran:
125  pips_user_warning("%dth parameter out of %d parameters not found for "
126  "function %s\n", i, nparams, entity_name(e));
127  break;
128  case is_language_c:
129  /* param can be undefined for C language: void foo(void)
130  * We do not have an entity corresponding to the 1st argument
131  */
132  break;
133  default:
134  pips_internal_error("Language unknown !");
135  break;
136  }
137  pc = gen_nconc( pc, words_type( t, ppdl, true ) );
138  /* Should be correct, but seems useless */
139  //if(!same_string_p(pn, "")) {
140  // pc = gen_nconc(pc, strdup(" "));
141  // pc = gen_nconc(pc, strdup(pn));
142  //}
143  } else {
144  switch(get_prettyprint_language_tag()) {
145  case is_language_fortran:
147  /*
148  * Variable type and dimensions will be (eventually) specified
149  * in declarations
150  */
152  break;
153  case is_language_c: {
154  /*
155  * We have to print variable's type, dimensions, ... with C
156  * This can be also a formal function
157  */
158  type t = type_undefined;
159  t = entity_type(param);
160  //list npdl = NIL;
161  /* FI: types and derived entities used for the formal
162  * parameters should be defined before end. If ever they are
163  * defined in the formal scope, they cannot be used
164  * elsewhere.
165  *
166  * FI: It might be better to implement the same behavior
167  * without building npdl, by passing an extra
168  * parameter... But you would have to check all call sites
169  * to c_words_entity().
170  */
171  //npdl = type_supporting_entities(npdl, t);
172  list entity_word = CHAIN_SWORD(NIL,entity_local_name(param));
173  pc = gen_nconc( pc,
174  c_words_entity( t,
175  entity_word,
176  ppdl /*&npdl*/ ) );
177  //gen_free_list(npdl);
178  break;
179  }
180  default:
181  pips_internal_error("Language unknown !");
182  break;
183  }
184  }
185  }
186  return ( pc );
187 }
gen_chunk gen_nth(int n, const list l)
to be used as ENTITY(gen_nth(3, l))...
Definition: list.c:710
#define pips_user_warning
Definition: misc-local.h:146
bool formal_label_replacement_p(entity)
Definition: variable.c:1797
entity find_ith_parameter(entity, int)
Definition: util.c:93
Definition: replace.c:135

References c_words_entity(), CHAIN_SWORD, entity_local_name(), entity_name, entity_type, entity_undefined_p, find_ith_parameter(), formal_label_replacement_p(), functional_parameters, gen_length(), gen_nconc(), gen_nth(), get_bool_property(), get_prettyprint_language_tag(), is_language_c, is_language_fortran, is_language_fortran95, NIL, PARAMETER, parameter_type, pips_assert, pips_internal_error, pips_user_warning, type_functional, type_functional_p, type_undefined, and words_type().

Referenced by sentence_head().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ words_qualifiers()

list words_qualifiers ( list  obj)
Parameters
objbj

Definition at line 795 of file declarations.c.

796 {
797  return generic_words_qualifiers(obj, true, true);
798 }

References generic_words_qualifiers().

Referenced by c_text_related_entities(), generic_c_words_simplified_entity(), get_symbol_table(), print_qualifiers(), sentence_head(), words_dimension(), and words_type().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ words_struct_reference()

static list words_struct_reference ( const char *  name1,
list  pc,
bool  init_p 
)
static

To print out a struct reference, such as "struct s".

Definition at line 1497 of file declarations.c.

1498 {
1499  pc = CHAIN_SWORD(pc,"struct ");
1500  if(strstr(name1,DUMMY_STRUCT_PREFIX)==NULL) {
1501  pc = CHAIN_SWORD(pc,name1);
1502  if(init_p)
1503  pc = CHAIN_SWORD(pc," ");
1504  else {
1505  // The semicolon is added somewhere else
1506  // pc = CHAIN_SWORD(pc,";");
1507  ;
1508  }
1509  }
1510  return pc;
1511 }

References CHAIN_SWORD, and DUMMY_STRUCT_PREFIX.

Referenced by c_text_related_entities().

+ Here is the caller graph for this function:

◆ Words_Type()

list Words_Type ( type  obj)
Parameters
objbj

Definition at line 891 of file declarations.c.

892 {
893  list pdl = NIL;
894  list pc = words_type(obj, &pdl, false);
895  return pc;
896 }

References NIL, and words_type().

+ Here is the call graph for this function:

◆ words_type()

list words_type ( type  obj,
list ppdl,
bool  argument_p 
)

obj is the type to describe

pdl is a list of already/previously declared data structures (not 100 % sure)

argument_p: the type is used as an argument type in a function declaration; if an argument appears with the "unknown" type it is explicitly declared "int"

returns a list of strings, called "words".

The default type is int. It can be skipped in direct declarations, but not as type of an argument in a function declaration

Parameters
objbj
ppdlpdl
argument_prgument_p

Definition at line 821 of file declarations.c.

822 {
823  list pc = NIL;
824  switch (type_tag(obj))
825  {
826  case is_type_variable:
827  {
828  // FI: the qualifiers are dropped
829  variable var = type_variable(obj);
830  basic b = variable_basic(var);
831  list ql = variable_qualifiers(var);
832  list dl = variable_dimensions(var);
833  pc = words_basic(b, ppdl);
834  pc = gen_nconc(pc, words_dimensions(dl, ppdl));
835  pc = gen_nconc(words_qualifiers(ql), pc);
836  break;
837  }
838  case is_type_void:
839  {
840  list ql = type_void(obj);
841  pc = CHAIN_SWORD(pc,"void");
842  pc = gen_nconc(words_qualifiers(ql), pc);
843  break;
844  }
845  case is_type_unknown:
846  {
847  /* The default type is int. It can be skipped in direct
848  declarations, but not as type of an argument in a function
849  declaration */
850  if(argument_p)
851  pc = CHAIN_SWORD(pc,"int");
852  break;
853  }
854  case is_type_struct:
855  {
856  pc = CHAIN_SWORD(pc,"struct");
857  break;
858  }
859  case is_type_union:
860  {
861  pc = CHAIN_SWORD(pc,"union");
862  break;
863  }
864  case is_type_enum:
865  {
866  pc = CHAIN_SWORD(pc,"enum");
867  break;
868  }
869  case is_type_functional:
870  {
871  string_buffer result = string_buffer_make(true);
872  string rs = string_undefined;
873  dump_functional(type_functional(obj), result);
874  rs = string_buffer_to_string(result);
875  pc = gen_nconc(pc, CONS(STRING, rs, NIL));
876  string_buffer_free(&result);
877  break;
878  }
879  case is_type_varargs:
880  {
881  pc = CHAIN_SWORD(pc,"...");
882  break;
883  }
884  default:
885  pips_internal_error("unexpected tag %d", type_tag(obj));
886  }
887  pips_debug(8, "End: \"\%s\"\n", list_to_string(pc));
888  return pc;
889 }
string string_buffer_to_string(const string_buffer)
return malloc'ed string from string buffer sb
void string_buffer_free(string_buffer *)
free string buffer structure, also free string contents according to the dup field
Definition: string_buffer.c:82
string_buffer string_buffer_make(bool dup)
allocate a new string buffer
Definition: string_buffer.c:58
void dump_functional(functional f, string_buffer result)
Definition: declarations.c:581
internally defined structure.
Definition: string_buffer.c:47

References argument_p(), CHAIN_SWORD, CONS, dump_functional(), gen_nconc(), is_type_enum, is_type_functional, is_type_struct, is_type_union, is_type_unknown, is_type_varargs, is_type_variable, is_type_void, list_to_string(), NIL, pips_debug, pips_internal_error, STRING, string_buffer_free(), string_buffer_make(), string_buffer_to_string(), string_undefined, type_functional, type_tag, type_variable, type_void, variable_basic, variable_dimensions, variable_qualifiers, words_basic(), words_dimensions(), and words_qualifiers().

Referenced by ensure_comment_consistency(), generic_c_words_simplified_entity(), print_type(), string_of_type(), type_to_full_string_definition(), words_basic(), words_parameters(), Words_Type(), and words_va_arg().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ words_union()

static list words_union ( const char *  name1,
list  pc,
bool  init_p 
)
static

Definition at line 1584 of file declarations.c.

1585 {
1586  pc = CHAIN_SWORD(pc,"union ");
1587  if(strstr(name1,DUMMY_UNION_PREFIX)==NULL) {
1588  pc = CHAIN_SWORD(pc,name1);
1589  if(init_p)
1590  pc = CHAIN_SWORD(pc," ");
1591  }
1592  //pc = CHAIN_SWORD(pc,"{");
1593  return pc;
1594 }

References CHAIN_SWORD, and DUMMY_UNION_PREFIX.

Referenced by c_text_related_entities().

+ Here is the caller graph for this function:

◆ words_value()

static list words_value ( value  obj)
static

Definition at line 74 of file declarations.c.

75 {
76  list pc=NIL;
77 
78  if (value_symbolic_p(obj)) {
80  }
81  else if (value_constant_p(obj)) {
82  pc = words_constant(value_constant(obj));
83  }
84  else if (value_unknown_p(obj)) {
85  // FI: Only good for Fortran
86  pc = CHAIN_SWORD(pc, "(*)");
87  }
88  else {
89  pips_internal_error("unexpected tag");
90  pc = NIL;
91  }
92 
93  return(pc);
94 }
static list words_constant(constant obj)
Definition: declarations.c:60
#define value_constant(x)
Definition: ri.h:3073
#define value_unknown_p(x)
Definition: ri.h:3077
#define value_constant_p(x)
Definition: ri.h:3071
#define value_symbolic_p(x)
Definition: ri.h:3068

References CHAIN_SWORD, NIL, pips_internal_error, symbolic_constant, value_constant, value_constant_p, value_symbolic, value_symbolic_p, value_unknown_p, and words_constant().

Referenced by words_basic().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ words_variable_or_function()

static list words_variable_or_function ( entity  module,
entity  e,
bool  is_first,
list  pc,
bool  in_type_declaration,
list ppdl,
bool  init_p 
)
static

This part is for declarator initialization if there is. If the entity is declared extern wrt current module, do not add this initialization

normal mode: module is defined

init_p is much more reliable

&& !extern_entity_p(module,e)

debugging mode: module is often undefined

it must be a pointer to a function. See encoding in set_entity_initial: how could this work with several pointers or pointer arrays to initialize?

Definition at line 1596 of file declarations.c.

1597 {
1598  const char* name = place_holder_variable_p(e)? "" : entity_user_name(e);
1599  type t = entity_type(e);
1600  //storage s = entity_storage(e);
1601  value val = entity_initial(e);
1602 
1604  is_first, in_type_declaration, ppdl));
1605  /* This part is for declarator initialization if there is. If the
1606  entity is declared extern wrt current module, do not add this
1607  initialization */
1608  if (/* normal mode: module is defined */
1610  /* init_p is much more reliable */
1611  /* && !extern_entity_p(module,e) */
1612  && !value_undefined_p(val)
1613  && init_p)
1614  /* debugging mode: module is often undefined */
1615  || (entity_undefined_p(module) && !value_undefined_p(val))) {
1616  if (value_expression_p(val)) {
1618  pc = CHAIN_SWORD(pc," = ");
1619  if (brace_expression_p(exp))
1620  pc = gen_nconc(pc,words_brace_expression(exp, ppdl));
1621  else {
1622  /* */
1624  }
1625  }
1626  else if(value_code_p(val)) {
1627  if(type_variable_p(t)) {
1628  /* it must be a pointer to a function. See encoding in
1629  * set_entity_initial: how could this work with several
1630  * pointers or pointer arrays to initialize?
1631  */
1633  if(!ENDP(il)) {
1634  statement is = STATEMENT(CAR(il));
1635  expression exp =
1637  pc = CHAIN_SWORD(pc," = ");
1638  pc = gen_nconc(pc,words_expression(exp, ppdl));
1639  }
1640  }
1641  }
1642  }
1643  return pc;
1644 }
list c_words_simplified_entity(type t, list name, bool is_first, bool in_type_declaration, list *ppdl)
The declaration list pointer ppdl is passed down to determine if an internal derived type must be ful...
list words_subexpression(expression obj, int precedence, bool leftmost, list *ppdl)
exported for cmfortran.c
Definition: misc.c:2674
#define ASSIGN_OPERATOR_PRECEDENCE
Definition: ri-util-local.h:96
bool brace_expression_p(expression e)
Return bool indicating if expression e is a brace expression.
Definition: expression.c:3384
#define value_undefined_p(x)
Definition: ri.h:3017
#define value_code_p(x)
Definition: ri.h:3065
#define code_initializations(x)
Definition: ri.h:788
#define sequence_statements(x)
Definition: ri.h:2360
#define value_code(x)
Definition: ri.h:3067
#define instruction_expression(x)
Definition: ri.h:1541
#define statement_instruction(x)
Definition: ri.h:2458
#define value_expression_p(x)
Definition: ri.h:3080
#define value_expression(x)
Definition: ri.h:3082
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413

References ASSIGN_OPERATOR_PRECEDENCE, brace_expression_p(), c_words_simplified_entity(), CAR, CHAIN_SWORD, code_initializations, ENDP, entity_initial, entity_type, entity_undefined_p, entity_user_name(), exp, gen_nconc(), instruction_expression, module, NIL, place_holder_variable_p(), sequence_statements, STATEMENT, statement_instruction, type_variable_p, value_code, value_code_p, value_expression, value_expression_p, value_undefined_p, words_brace_expression(), words_expression(), and words_subexpression().

Referenced by c_text_related_entities().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: