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

Go to the source code of this file.

Data Structures

struct  macro_t
 

Functions

void parser_init_macros_support (void)
 next available chunk More...
 
void parser_close_macros_support (void)
 
static macro_tfind_entity_macro (entity e)
 
bool parser_entity_macro_p (entity e)
 
void parser_add_a_macro (call c, expression e)
 
static bool call_flt (call c)
 
static bool untrusted_call_p (expression e)
 
static bool expr_flt (expression e)
 
static void expr_rwt (expression e)
 
static void substitute_expression_in_expression (expression tree, expression initial, expression replacement)
 substitutes occurences of initial by replacement in tree More...
 
void reset_substitute_expression_in_expression (void)
 
void parser_macro_expansion (expression e)
 
void parser_substitute_all_macros (statement s)
 
void parser_substitute_all_macros_in_expression (expression e)
 

Variables

static macro_tcurrent_macros
 
static int current_macros_size = 0
 
static int current_macro_index = 0
 
static bool some_call
 is there a call to some untrusted function? More...
 
static expression s_init = expression_undefined
 must take care not to substitute in an inserted expression More...
 
static expression s_repl = expression_undefined
 
static list already_subs = NIL
 of expression More...
 

Function Documentation

◆ call_flt()

static bool call_flt ( call  c)
static

else untrusted!

Definition at line 152 of file macros.c.

153 {
156  return true;
157  /* else untrusted!
158  */
159  some_call = true;
160  gen_recurse_stop(NULL);
161  return false;
162 }
void gen_recurse_stop(void *obj)
Tells the recursion not to go in this object.
Definition: genClib.c:3251
static bool some_call
is there a call to some untrusted function?
Definition: macros.c:150
#define call_function(x)
Definition: ri.h:709
#define value_intrinsic_p(x)
Definition: ri.h:3074
#define value_constant_p(x)
Definition: ri.h:3071
#define value_symbolic_p(x)
Definition: ri.h:3068
#define entity_initial(x)
Definition: ri.h:2796

References call_function, entity_initial, gen_recurse_stop(), some_call, value_constant_p, value_intrinsic_p, and value_symbolic_p.

Referenced by untrusted_call_p().

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

◆ expr_flt()

static bool expr_flt ( expression  e)
static

Definition at line 180 of file macros.c.

181 {
182  return !gen_in_list_p(e, already_subs);
183 }
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734
static list already_subs
of expression
Definition: macros.c:178

References already_subs, and gen_in_list_p().

Referenced by substitute_expression_in_expression().

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

◆ expr_rwt()

static void expr_rwt ( expression  e)
static

Definition at line 185 of file macros.c.

186 {
187  if (expression_equal_p(s_init, e))
188  {
192  }
193 }
syntax copy_syntax(syntax p)
SYNTAX.
Definition: ri.c:2442
void free_syntax(syntax p)
Definition: ri.c:2445
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
static expression s_init
must take care not to substitute in an inserted expression
Definition: macros.c:177
static expression s_repl
Definition: macros.c:177
bool expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define expression_syntax(x)
Definition: ri.h:1247

References already_subs, CONS, copy_syntax(), EXPRESSION, expression_equal_p(), expression_syntax, free_syntax(), s_init, and s_repl.

Referenced by substitute_expression_in_expression().

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

◆ find_entity_macro()

static macro_t* find_entity_macro ( entity  e)
static

not found

Definition at line 98 of file macros.c.

99 {
100  int i;
101  for (i=0; i<current_macro_index; i++)
103  return &current_macros[i];
104 
105  return NULL; /* not found */
106 }
static int current_macro_index
Definition: macros.c:55
static macro_t * current_macros
Definition: macros.c:53
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321

References call_function, current_macro_index, current_macros, and same_entity_p().

Referenced by parser_add_a_macro(), parser_entity_macro_p(), and parser_macro_expansion().

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

◆ parser_add_a_macro()

void parser_add_a_macro ( call  c,
expression  e 
)

resize!

expand macros in the macro! It is ok, because referenced macros must appear in preceding lines (F77 15-5, line 3-5).

store the result.

Definition at line 113 of file macros.c.

114 {
115  entity macro = call_function(c);
116 
117  pips_debug(5, "adding macro %s\n", entity_name(macro));
118  pips_assert("macros support initialized", current_macros_size>0);
119 
120  if (current_macro_index>=current_macros_size) /* resize! */
121  {
123  current_macros = (macro_t*)
124  realloc(current_macros, sizeof(macro_t)*current_macros_size);
125  pips_assert("realloc ok", current_macros);
126  }
127 
128  if (find_entity_macro(macro) != NULL) {
129  pips_user_warning("Macro \"%s\" is not yet defined.\n",
130  entity_name(macro));
131  ParserError("parser_add_a_macro",
132  "It may be an undeclared array.\n");
133  }
134 
135  /* expand macros in the macro! It is ok, because
136  * referenced macros must appear in preceding lines (F77 15-5, line 3-5).
137  */
139 
140  /* store the result.
141  */
145 }
static int current_macros_size
Definition: macros.c:54
void parser_substitute_all_macros_in_expression(expression e)
Definition: macros.c:302
static macro_t * find_entity_macro(entity e)
Definition: macros.c:98
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_user_warning
Definition: misc-local.h:146
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define entity_name(x)
Definition: ri.h:2790
Definition: macros.c:48
call lhs
Definition: macros.c:49
expression rhs
Definition: macros.c:50
bool ParserError(const char *f, const char *m)
Definition: parser.c:116

References call_function, current_macro_index, current_macros, current_macros_size, entity_name, find_entity_macro(), macro_t::lhs, parser_substitute_all_macros_in_expression(), ParserError(), pips_assert, pips_debug, pips_user_warning, and macro_t::rhs.

Referenced by MakeAssignInst().

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

◆ parser_close_macros_support()

void parser_close_macros_support ( void  )

what about the entity? It might exist such a real top-level entity... what if added as a callee... the entity should be destroyed... best would be to have it as a local entity, and have the calles and top-level updates delayed.

Definition at line 72 of file macros.c.

73 {
74  pips_debug(5, "closing macro-expansion support stuff\n");
75 
77  {
78  call c;
79  entity macro;
80 
83 
84  macro = call_function(c);
85  free_call(c);
86 
87  /* what about the entity?
88  * It might exist such a real top-level entity...
89  * what if added as a callee...
90  * the entity should be destroyed...
91  * best would be to have it as a local entity,
92  * and have the calles and top-level updates delayed.
93  */
95  }
96 }
void free_expression(expression p)
Definition: ri.c:853
void free_call(call p)
Definition: ri.c:236
void remove_from_called_modules(entity e)
macros are added, although they should not have been.
Definition: procedure.c:354

References call_function, current_macro_index, current_macros, free_call(), free_expression(), macro_t::lhs, pips_debug, and remove_from_called_modules().

Referenced by EndOfProcedure().

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

◆ parser_entity_macro_p()

bool parser_entity_macro_p ( entity  e)

Definition at line 108 of file macros.c.

109 {
110  return find_entity_macro(e)==NULL;
111 }

References find_entity_macro().

+ Here is the call graph for this function:

◆ parser_init_macros_support()

void parser_init_macros_support ( void  )

next available chunk

macros.c

??? memory leak...

Definition at line 57 of file macros.c.

58 {
59  pips_debug(5, "initializing macro-expansion support stuff\n");
60 
61  current_macro_index = 0; /* ??? memory leak... */
62 
63  if (current_macros_size==0)
64  {
68  pips_assert("malloc ok", current_macros);
69  }
70 }
void * malloc(YYSIZE_T)

References current_macro_index, current_macros, current_macros_size, malloc(), pips_assert, and pips_debug.

Referenced by the_actual_parser().

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

◆ parser_macro_expansion()

void parser_macro_expansion ( expression  e)

of expression

get the macro definition.

duplicated, for latter subs.

replace each formal by its actual.

MUST be a simple reference

if the replacement is a constant, or a reference without calls to external functions, it should be safe

it is important to keep the same expression, for gen_recurse use.

Definition at line 224 of file macros.c.

225 {
226  bool warned = false;
227  macro_t * def;
228  call c, lhs;
229  entity macro;
230  expression rhs;
231  list /* of expression */ lactuals, lformals;
232 
233  if (!expression_call_p(e)) return;
234 
236  macro = call_function(c);
237  lactuals = call_arguments(c);
238 
239  /* get the macro definition. */
240  def = find_entity_macro(macro);
241 
242  if (def==NULL) {
243  pips_debug(5, "no macro definition for %s\n", entity_name(macro));
244  return;
245  }
246 
247  lhs = def->lhs;
248  rhs = copy_expression(def->rhs); /* duplicated, for latter subs. */
249 
250  pips_assert("right macro function", macro == call_function(lhs));
251 
252  lformals = call_arguments(lhs);
253 
254  pips_assert("same #args", gen_length(lactuals)==gen_length(lformals));
255 
257 
258  /* replace each formal by its actual.
259  */
260  for (; !ENDP(lactuals); POP(lactuals), POP(lformals))
261  {
262  expression actu, form;
263 
264  form = EXPRESSION(CAR(lformals)); /* MUST be a simple reference */
265  pips_assert("dummy arg ok",
266  expression_reference_p(form) &&
268 
269  /* if the replacement is a constant, or a reference without
270  * calls to external functions, it should be safe
271  */
272  actu = EXPRESSION(CAR(lactuals));
273 
274  if (!warned && untrusted_call_p(actu)) {
275  pips_user_warning("maybe non safe substitution of macro %s!\n",
276  module_local_name(macro));
277  warned = true;
278  }
279 
280  substitute_expression_in_expression(rhs, form, actu);
281  }
282 
284 
285  /* it is important to keep the same expression, for gen_recurse use.
286  */
290  free(rhs);
291 }
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
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
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
void reset_substitute_expression_in_expression(void)
Definition: macros.c:218
static bool untrusted_call_p(expression e)
Definition: macros.c:164
static void substitute_expression_in_expression(expression tree, expression initial, expression replacement)
substitutes occurences of initial by replacement in tree
Definition: macros.c:197
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
bool expression_call_p(expression e)
Definition: expression.c:415
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
#define syntax_reference(x)
Definition: ri.h:2730
#define reference_indices(x)
Definition: ri.h:2328
#define syntax_call(x)
Definition: ri.h:2736
#define syntax_undefined
Definition: ri.h:2676
#define call_arguments(x)
Definition: ri.h:711
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References call_arguments, call_function, CAR, copy_expression(), ENDP, entity_name, EXPRESSION, expression_call_p(), expression_reference_p(), expression_syntax, find_entity_macro(), free(), free_syntax(), gen_length(), macro_t::lhs, module_local_name(), pips_assert, pips_debug, pips_user_warning, POP, reference_indices, reset_substitute_expression_in_expression(), macro_t::rhs, substitute_expression_in_expression(), syntax_call, syntax_reference, syntax_undefined, and untrusted_call_p().

Referenced by parser_substitute_all_macros().

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

◆ parser_substitute_all_macros()

void parser_substitute_all_macros ( statement  s)

Definition at line 294 of file macros.c.

295 {
296  if (current_macro_index>0 &&
297  get_bool_property("PARSER_EXPAND_STATEMENT_FUNCTIONS"))
299 }
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
void parser_macro_expansion(expression e)
Definition: macros.c:224
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154

References current_macro_index, expression_domain, gen_recurse, gen_true(), get_bool_property(), and parser_macro_expansion().

Referenced by EndOfProcedure(), and parser_substitute_all_macros_in_expression().

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

◆ parser_substitute_all_macros_in_expression()

void parser_substitute_all_macros_in_expression ( expression  e)

Definition at line 302 of file macros.c.

303 {
305 }
void parser_substitute_all_macros(statement s)
Definition: macros.c:294

References parser_substitute_all_macros().

Referenced by parser_add_a_macro().

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

◆ reset_substitute_expression_in_expression()

void reset_substitute_expression_in_expression ( void  )

Definition at line 218 of file macros.c.

219 {
221  already_subs = NIL;
222 }
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327

References already_subs, gen_free_list(), and NIL.

Referenced by parser_macro_expansion().

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

◆ substitute_expression_in_expression()

static void substitute_expression_in_expression ( expression  tree,
expression  initial,
expression  replacement 
)
static

substitutes occurences of initial by replacement in tree

ifdebug(8) {

pips_debug(8, "tree/initial/replacement\n");

print_expression(tree);

print_expression(initial);

print_expression(replacement);

}

Definition at line 197 of file macros.c.

201 {
202  /* ifdebug(8) { */
203  /* pips_debug(8, "tree/initial/replacement\n"); */
204  /* print_expression(tree); */
205  /* print_expression(initial); */
206  /* print_expression(replacement); */
207  /* } */
208 
209  s_init = initial;
210  s_repl = replacement;
211 
213 
216 }
static void expr_rwt(expression e)
Definition: macros.c:185
static bool expr_flt(expression e)
Definition: macros.c:180
#define expression_undefined
Definition: ri.h:1223

References expr_flt(), expr_rwt(), expression_domain, expression_undefined, gen_recurse, s_init, and s_repl.

Referenced by parser_macro_expansion().

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

◆ untrusted_call_p()

static bool untrusted_call_p ( expression  e)
static

Definition at line 164 of file macros.c.

165 {
166  some_call = false;
168  return some_call;
169 }
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
static bool call_flt(call c)
Definition: macros.c:152
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58

References call_domain, call_flt(), gen_null(), gen_recurse, and some_call.

Referenced by parser_macro_expansion().

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

Variable Documentation

◆ already_subs

list already_subs = NIL
static

of expression

Definition at line 178 of file macros.c.

Referenced by expr_flt(), expr_rwt(), and reset_substitute_expression_in_expression().

◆ current_macro_index

◆ current_macros

macro_t* current_macros
static

◆ current_macros_size

int current_macros_size = 0
static

Definition at line 54 of file macros.c.

Referenced by parser_add_a_macro(), and parser_init_macros_support().

◆ s_init

must take care not to substitute in an inserted expression

Definition at line 177 of file macros.c.

Referenced by expr_rwt(), MakeAssignedOrComputedGotoInst(), and substitute_expression_in_expression().

◆ s_repl

Definition at line 177 of file macros.c.

Referenced by expr_rwt(), and substitute_expression_in_expression().

◆ some_call

bool some_call
static

is there a call to some untrusted function?

Definition at line 150 of file macros.c.

Referenced by call_flt(), and untrusted_call_p().