1 /*
2  * Copyright (c) 2016-2018, NVIDIA CORPORATION.  All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 /**
19     \file
20     \brief Manage the scope stack.
21 */
22 
23 #include "gbldefs.h"
24 #include "global.h"
25 #include "error.h"
26 #include "symtab.h"
27 #include "symutl.h"
28 #include "ccffinfo.h"
29 #include "semant.h"
30 
31 static SCOPESTACK *push_scope(void);
32 static void pop_scope(void);
33 static const char *kind_to_string(SCOPEKIND kind);
34 
35 /** \brief Initialize the scope stack.
36 
37     It starts with one frame representing the outer scope,
38     with no associated symbol.
39  */
40 void
scopestack_init()41 scopestack_init()
42 {
43   SCOPESTACK *scope;
44   if (sem.scope_stack == NULL) {
45     sem.scope_size = 10;
46     NEW(sem.scope_stack, SCOPESTACK, sem.scope_size);
47   }
48   sem.scope_level = 0;
49   sem.scope_extra = 5;
50   scope = curr_scope();
51   BZERO(scope, SCOPESTACK, 1);
52   scope->kind = SCOPE_OUTER;
53   scope->symavl = stb.stg_avail;
54   scope->sym = 0;
55 }
56 
57 /** \brief Return the scope at the top of the scope stack. */
58 SCOPESTACK *
curr_scope()59 curr_scope()
60 {
61   return get_scope(0);
62 }
63 
64 /** \brief Get an entry in the scope stack.
65     \param level Level of the entry to return: 0 means top and negative is
66            relative to the top.
67  */
68 SCOPESTACK *
get_scope(int level)69 get_scope(int level)
70 {
71   if (level <= 0) {
72     level += sem.scope_level;
73   }
74   if (level < 0 || level >= sem.scope_size) {
75 #if DEBUG
76     dumpscope(gbl.dbgfil);
77 #endif
78     interr("bad scope stack level", level, ERR_Fatal);
79   }
80   return &sem.scope_stack[level];
81 }
82 
83 /** \brief Return the level of this entry in the scope stack
84            or -1 if \a scope is null.
85  */
86 int
get_scope_level(SCOPESTACK * scope)87 get_scope_level(SCOPESTACK *scope)
88 {
89   if (scope == 0) {
90     return -1;
91   } else {
92     int level = scope - sem.scope_stack;
93     assert(level >= 0 && level <= sem.scope_level, "bad scope stack level",
94            level, ERR_Fatal);
95     return level;
96   }
97 }
98 
99 /** \brief Return the next entry below this one in the scope stack; 0 if none.
100     If scope is 0, return the top of the stack.
101  */
102 SCOPESTACK *
next_scope(SCOPESTACK * scope)103 next_scope(SCOPESTACK *scope)
104 {
105   int sl = get_scope_level(scope);
106   if (sl < 0) {
107     return curr_scope();
108   } else if (sl == 0) {
109     return 0;
110   } else {
111     return scope - 1;
112   }
113 }
114 
115 /** \brief Return the next entry below scope that has this sptr assocated with
116    it.
117            If scope is 0, search from the top of the stack.
118  */
119 SCOPESTACK *
next_scope_sptr(SCOPESTACK * scope,int sptr)120 next_scope_sptr(SCOPESTACK *scope, int sptr)
121 {
122   while ((scope = next_scope(scope)) != 0) {
123     if (scope->sptr == sptr) {
124       return scope;
125     }
126   }
127   return 0;
128 }
129 
130 /** \brief Return the next entry below scope that has this kind.
131            If scope is 0, search from the top of the stack.
132  */
133 SCOPESTACK *
next_scope_kind(SCOPESTACK * scope,SCOPEKIND kind)134 next_scope_kind(SCOPESTACK *scope, SCOPEKIND kind)
135 {
136   while ((scope = next_scope(scope)) != 0) {
137     if (scope->kind == kind) {
138       return scope;
139     }
140   }
141   return 0;
142 }
143 
144 /** \brief Return the next entry below scope that has this kind and sptr.
145            If scope is 0, search from the top of the stack.
146  */
147 SCOPESTACK *
next_scope_kind_sptr(SCOPESTACK * scope,SCOPEKIND kind,int sptr)148 next_scope_kind_sptr(SCOPESTACK *scope, SCOPEKIND kind, int sptr)
149 {
150   while ((scope = next_scope_kind(scope, kind)) != 0) {
151     if (scope->sptr == sptr) {
152       return scope;
153     }
154   }
155   return 0;
156 }
157 
158 /** \brief Return the next entry below scope that has this kind and symbol name.
159            If scope is 0, search from the top of the stack.
160  */
161 SCOPESTACK *
next_scope_kind_symname(SCOPESTACK * scope,SCOPEKIND kind,const char * symname)162 next_scope_kind_symname(SCOPESTACK *scope, SCOPEKIND kind, const char *symname)
163 {
164   while ((scope = next_scope_kind(scope, kind)) != 0) {
165     if (strcmp(symname, SYMNAME(scope->sptr)) == 0) {
166       return scope;
167     }
168   }
169   return 0;
170 }
171 
172 /** \brief Return the USE module scope for the module associated with this
173            symbol, or -1 if none.
174  */
175 int
have_use_scope(int sptr)176 have_use_scope(int sptr)
177 {
178   SCOPESTACK *scope = 0;
179   if (sem.scope_stack == NULL) {
180     return -1;
181   }
182   while ((scope = next_scope(scope)) != 0) {
183     if (scope->kind == SCOPE_USE && scope->sptr == sptr) {
184       return get_scope_level(scope);
185     }
186     if (!scope->open) {
187       break;
188     }
189   }
190   return -1;
191 }
192 
193 /** \brief Return TRUE if sptr is in the exception list for this scope
194     at this level.
195  */
196 LOGICAL
is_except_in_scope(SCOPESTACK * scope,int sptr)197 is_except_in_scope(SCOPESTACK *scope, int sptr)
198 {
199   return sym_in_sym_list(sptr, scope->except);
200 }
201 
202 /** \brief Return TRUE if scope is private and has sptr in its 'only' list.
203  */
204 LOGICAL
is_private_in_scope(SCOPESTACK * scope,int sptr)205 is_private_in_scope(SCOPESTACK *scope, int sptr)
206 {
207   return scope->Private && !sym_in_sym_list(sptr, scope->only);
208 }
209 
210 /** \brief Push an entry on the scope stack with this symbol and kind.
211  */
212 void
push_scope_level(int sptr,SCOPEKIND kind)213 push_scope_level(int sptr, SCOPEKIND kind)
214 {
215   SCOPESTACK *scope;
216   if (sem.scope_stack == NULL) {
217     return;
218   }
219   scope = push_scope();
220   switch (kind) {
221   case SCOPE_SUBPROGRAM:
222     if (sem.which_pass == 1) {
223       setfile(1, SYMNAME(sptr), 0);
224     }
225     scope->sptr = sptr;
226     break;
227   case SCOPE_NORMAL:
228   case SCOPE_MODULE:
229   case SCOPE_USE:
230     scope->sptr = sptr;
231     break;
232   case SCOPE_OUTER:
233   case SCOPE_INTERFACE:
234   case SCOPE_PAR:
235     ++sem.scope_extra;
236     scope->sptr = sem.scope_extra;
237     break;
238   default:
239     interr("push_scope_level: unknown scope kind", kind, ERR_Warning);
240   }
241   /*
242    * When entering a parallel scope, the current scope is left to be the
243    * scope of the outer nonparallel scope containing the parallel region.
244    */
245   if (kind != SCOPE_PAR) {
246     stb.curr_scope = scope->sptr;
247   }
248   scope->kind = kind;
249   scope->open = TRUE;
250   scope->symavl = stb.stg_avail;
251   scope->Private = FALSE;
252   scope->sym = 0;
253   scope->uplevel_sptr = 0;
254 #if DEBUG
255   if (DBGBIT(5, 0x200)) {
256     fprintf(gbl.dbgfil, "\n++++++++  push_scope_level(%s)  pass=%d  line=%d\n",
257             kind_to_string(kind), sem.which_pass, gbl.lineno);
258     dumpscope(gbl.dbgfil);
259   }
260 #endif
261 }
262 
263 /** \brief Push an interface entry on the scope stack and mark it closed.
264  */
265 void
push_iface_scope_level()266 push_iface_scope_level()
267 {
268   push_scope_level(0, SCOPE_INTERFACE);
269   curr_scope()->open = FALSE;
270 }
271 
272 /*
273    Pop scope stack until popping off a frame of this kind.
274  */
275 void
pop_scope_level(SCOPEKIND kind)276 pop_scope_level(SCOPEKIND kind)
277 {
278   if (sem.scope_stack == NULL) {
279     return;
280   }
281   if (sem.scope_level == 0) {
282     interr("trying to pop too many scope levels", sem.scope_level, ERR_Severe);
283     return;
284   }
285 
286   /* pop scope stack until popping a frame with this kind */
287   for (;;) {
288     int newscope;
289     /* pop symbols */
290     int top = curr_scope()->symavl;
291     int scope = curr_scope()->sptr;
292     SCOPEKIND curr_kind = curr_scope()->kind;
293     switch (curr_kind) {
294     case SCOPE_INTERFACE:
295       newscope = get_scope(-1)->sptr;
296       if (newscope != scope) {
297         int sptr;
298         for (sptr = stb.stg_avail - 1; sptr >= top; --sptr) {
299           if (SCOPEG(sptr) == scope) {
300             /* rehost to outer level */
301             SCOPEP(sptr, newscope);
302           }
303         }
304       }
305       break;
306     default:
307       if (sem.interface && STYPEG(scope) != ST_MODULE) {
308         int sptr;
309         /* in an interface block; remove the symbols */
310         for (sptr = stb.stg_avail - 1; sptr >= top; --sptr) {
311           if (SCOPEG(sptr) == scope) {
312             IGNOREP(sptr, 1);
313           }
314         }
315       }
316       break;
317     }
318     pop_scope();
319     if (curr_kind == kind) {
320       break;
321     }
322   }
323   /*
324    * When leaving a parallel scope, the current scope doesn't need to be
325    * reset since it should always be the scope of the nonparallel region
326    * containing the parallel region.
327    */
328   if (kind != SCOPE_PAR) {
329     if (sem.scope_level > 0) {
330       stb.curr_scope = curr_scope()->sptr;
331     } else { /* leave scope symbol as most recent one */
332       stb.curr_scope = sem.scope_stack[1].sptr;
333     }
334   }
335 #if DEBUG
336   if (DBGBIT(5, 0x200)) {
337     fprintf(gbl.dbgfil, "\n--------  pop_scope_level(%s)  pass=%d  line=%d\n",
338             kind_to_string(kind), sem.which_pass, gbl.lineno);
339     dumpscope(gbl.dbgfil);
340   }
341 #endif
342 }
343 
344 static SCOPESTACK saved_scope_stack[1];
345 static int count_scope_saved = 0;
346 
347 /** \brief Pop the current scope into a save area; restore with
348  * restore_scope_level() */
349 void
save_scope_level(void)350 save_scope_level(void)
351 {
352   if (count_scope_saved >= 1) {
353     interr("trying to save too many scope levels", count_scope_saved, 3);
354     return;
355   }
356   saved_scope_stack[count_scope_saved++] = *curr_scope();
357   pop_scope();
358   stb.curr_scope = curr_scope()->sptr;
359 #if DEBUG
360   if (DBGBIT(5, 0x200)) {
361     fprintf(gbl.dbgfil, "\n--------  save_scope_level  pass=%d  line=%d\n",
362             sem.which_pass, gbl.lineno);
363     dumpscope(gbl.dbgfil);
364   }
365 #endif
366 }
367 
368 /** \brief Restore the scope that was saved by save_scope_level() */
369 void
restore_scope_level(void)370 restore_scope_level(void)
371 {
372   if (count_scope_saved <= 0) {
373     interr("trying to restore too many scope levels", count_scope_saved, 3);
374     return;
375   }
376   *push_scope() = saved_scope_stack[--count_scope_saved];
377   stb.curr_scope = curr_scope()->sptr;
378 #if DEBUG
379   if (DBGBIT(5, 0x200)) {
380     fprintf(gbl.dbgfil, "\n++++++++  restore_scope_level  pass=%d  line=%d\n",
381             sem.which_pass, gbl.lineno);
382     dumpscope(gbl.dbgfil);
383   }
384 #endif
385 }
386 
387 void
par_push_scope(LOGICAL bind_to_outer)388 par_push_scope(LOGICAL bind_to_outer)
389 {
390   SCOPESTACK *scope, *next_scope;
391   SC_KIND prev_sc = sem.sc;
392   if (curr_scope()->kind != SCOPE_PAR && sem.parallel >= 1) {
393     sem.sc = SC_PRIVATE;
394   } else if (sem.task) {
395     sem.sc = SC_PRIVATE;
396   }
397   else if (sem.teams >= 1) {
398     sem.sc = SC_PRIVATE;
399   } else if (sem.target && sem.parallel >= 1) {
400     sem.sc = SC_PRIVATE;
401   }
402   push_scope_level(0, SCOPE_PAR);
403   scope = curr_scope();
404   next_scope = get_scope(-1); /* next to top of stack */
405   if (!bind_to_outer || next_scope->kind != SCOPE_PAR) {
406     scope->rgn_scope = sem.scope_level;
407     scope->par_scope = PAR_SCOPE_SHARED;
408   } else {
409     scope->rgn_scope = next_scope->rgn_scope;
410     scope->par_scope = next_scope->par_scope;
411     scope->end_prologue = next_scope->end_prologue;
412   }
413   scope->di_par = sem.doif_depth;
414   scope->shared_list = NULL;
415   scope->prev_sc = prev_sc;
416   enter_lexical_block(flg.debug && !XBIT(123, 0x400));
417 }
418 
419 void
par_pop_scope(void)420 par_pop_scope(void)
421 {
422   SCOPE_SYM *symp;
423   int blksym;
424   /*
425    * Restore the scope of any symbols which appeared in a SHARED
426    * clause -- this is only needed if the DEFAULT scope is 'PRIVATE' or
427    * 'NONE".
428    */
429   for (symp = curr_scope()->shared_list; symp != NULL; symp = symp->next) {
430     SCOPEP(symp->sptr, symp->scope);
431   }
432   blksym = curr_scope()->sym;
433   if (blksym) {
434     exit_lexical_block(flg.debug && !XBIT(123, 0x400));
435   }
436 
437   sem.sc = curr_scope()->prev_sc;
438   pop_scope_level(SCOPE_PAR);
439   if (curr_scope()->kind != SCOPE_PAR) {
440     sem.sc = SC_LOCAL;
441   }
442 }
443 
444 static SCOPESTACK *
push_scope(void)445 push_scope(void)
446 {
447   ++sem.scope_level;
448   NEED(sem.scope_level + 1, sem.scope_stack, SCOPESTACK, sem.scope_size,
449        sem.scope_size + 10);
450   BZERO(sem.scope_stack + sem.scope_level, SCOPESTACK, 1);
451   return curr_scope();
452 }
453 
454 static void
pop_scope(void)455 pop_scope(void)
456 {
457   --sem.scope_level;
458   assert(sem.scope_level >= 0, "attempt to pop empty scope stack",
459          sem.scope_level, ERR_Fatal);
460 }
461 
462 #if DEBUG
463 void
dumpscope(FILE * f)464 dumpscope(FILE *f)
465 {
466   int sl;
467   if (f == NULL) {
468     f = stderr;
469   }
470   if (sem.scope_stack == NULL) {
471     fprintf(f, "no scope stack\n");
472     return;
473   }
474   for (sl = 0; sl <= sem.scope_level; ++sl) {
475     dump_one_scope(sl, f);
476   }
477 }
478 
479 void
dump_one_scope(int sl,FILE * f)480 dump_one_scope(int sl, FILE *f)
481 {
482   SCOPESTACK *scope;
483   SPTR sptr;
484   if (f == NULL) {
485     f = stderr;
486   }
487   if (sl < 0 || sl >= sem.scope_size) {
488     interr("dump_one_scope: bad scope stack level", sl, ERR_Warning);
489     return;
490   }
491   scope = sem.scope_stack + sl;
492   sptr = scope->sptr;
493   fprintf(f, "%ccope %2d. %-11s %-7s %-8s symavl=%3d  %d=%s\n",
494           sem.which_pass ? 'S' : 's', sl, kind_to_string(scope->kind),
495           scope->open ? "open" : "closed",
496           scope->Private ? "private" : "public",
497           scope->symavl, sptr,
498           sptr >= stb.firstosym ? SYMNAME(sptr) : "");
499   if (scope->except) {
500     int ex;
501     fprintf(f, "+ except");
502     for (ex = scope->except; ex; ex = SYMI_NEXT(ex)) {
503       fprintf(f, " %d(%s)", SYMI_SPTR(ex), SYMNAME(SYMI_SPTR(ex)));
504     }
505     fprintf(f, "\n");
506   }
507   if (scope->import) {
508     int im;
509     fprintf(f, "+ import");
510     for (im = scope->import; im; im = SYMI_NEXT(im)) {
511       fprintf(f, " %d(%s)", SYMI_SPTR(im), SYMNAME(SYMI_SPTR(im)));
512     }
513     fprintf(f, "\n");
514   }
515 }
516 
517 static const char *
kind_to_string(SCOPEKIND kind)518 kind_to_string(SCOPEKIND kind)
519 {
520   switch (kind) {
521   case SCOPE_OUTER:      return "Outer";
522   case SCOPE_NORMAL:     return "Normal";
523   case SCOPE_SUBPROGRAM: return "Subprogram";
524   case SCOPE_MODULE:     return "Module";
525   case SCOPE_INTERFACE:  return "Interface";
526   case SCOPE_USE:        return "Use";
527   case SCOPE_PAR:        return "Par";
528   default:               return "<unknown>";
529   }
530 }
531 
532 #endif
533