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