aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sem.ads
blob: 8b38c33a2ae5c89918b297611d4f29cffc608717 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                                  S E M                                   --
--                                                                          --
--                                 S p e c                                  --
--                                                                          --
--          Copyright (C) 1992-2007, Free Software Foundation, Inc.         --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 2,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT;  see file COPYING.  If not, write --
-- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
-- Boston, MA 02110-1301, USA.                                              --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

--------------------------------------
-- Semantic Analysis: General Model --
--------------------------------------

--  Semantic processing involves 3 phases which are highly interwined
--  (ie mutually recursive):

--    Analysis     implements the bulk of semantic analysis such as
--                 name analysis and type resolution for declarations,
--                 instructions and expressions.  The main routine
--                 driving this process is procedure Analyze given below.
--                 This analysis phase is really a bottom up pass that is
--                 achieved during the recursive traversal performed by the
--                 Analyze_... procedures implemented in the sem_* packages.
--                 For expressions this phase determines unambiguous types
--                 and collects sets of possible types where the
--                 interpretation is potentially ambiguous.

--    Resolution   is carried out only for expressions to finish type
--                 resolution that was initiated but not necessarily
--                 completed during analysis (because of overloading
--                 ambiguities). Specifically, after completing the bottom
--                 up pass carried out during analysis for expressions, the
--                 Resolve routine (see the spec of sem_res for more info)
--                 is called to perform a top down resolution with
--                 recursive calls to itself to resolve operands.

--    Expansion    if we are not generating code this phase is a no-op.
--                 otherwise this phase expands, ie transforms, original
--                 declaration, expressions or instructions into simpler
--                 structures that can be handled by the back-end. This
--                 phase is also in charge of generating code which is
--                 implicit in the original source (for instance for
--                 default initializations, controlled types, etc.)
--                 There are two separate instances where expansion is
--                 invoked. For declarations and instructions, expansion is
--                 invoked just after analysis since no resolution needs
--                 to be performed. For expressions, expansion is done just
--                 after resolution. In both cases expansion is done from the
--                 bottom up just before the end of Analyze for instructions
--                 and declarations or the call to Resolve for expressions.
--                 The main routine driving expansion is Expand.
--                 See the spec of Expander for more details.

--  To summarize, in normal code generation mode we recursively traverse the
--  abstract syntax tree top-down performing semantic analysis bottom
--  up. For instructions and declarations, before the call to the Analyze
--  routine completes we perform expansion since at that point we have all
--  semantic information needed. For expression nodes, after the call to
--  Analysis terminates we invoke the Resolve routine to transmit top-down
--  the type that was gathered by Analyze which will resolve possible
--  ambiguities in the expression. Just before the call to Resolve
--  terminates, the expression can be expanded since all the semantic
--  information is available at that point.

--  If we are not generating code then the expansion phase is a no-op

--  When generating code there are a number of exceptions to the basic
--  Analysis-Resolution-Expansion model for expressions. The most prominent
--  examples are the handling of default expressions and aggregates.

----------------------------------------------------
-- Handling of Default and Per-Object Expressions --
----------------------------------------------------

--  The default expressions in component declarations and in procedure
--  specifications (but not the ones in object declarations) are quite
--  tricky to handle. The problem is that some processing is required
--  at the point where the expression appears:

--    visibility analysis (including user defined operators)
--    freezing of static expressions

--  but other processing must be deferred until the enclosing entity
--  (record or procedure specification) is frozen:

--    freezing of any other types in the expression
--    expansion

--  A similar situation occurs with the argument of priority and interrupt
--  priority pragmas that appear in task and protected definition specs and
--  other cases of per-object expressions (see RM 3.8(18)).

--  Expansion has to be deferred since you can't generate code for
--  expressions that refernce types that have not been frozen yet. As an
--  example, consider the following:

--      type x is delta 0.5 range -10.0 .. +10.0;
--      ...
--      type q is record
--        xx : x := y * z;
--      end record;

--      for x'small use 0.25

--  The expander is in charge of dealing with fixed-point, and of course
--  the small declaration, which is not too late, since the declaration of
--  type q does *not* freeze type x, definitely affects the expanded code.

--  Another reason that we cannot expand early is that expansion can generate
--  range checks. These range checks need to be inserted not at the point of
--  definition but at the point of use. The whole point here is that the value
--  of the expression cannot be obtained at the point of declaration, only at
--  the point of use.

--  Generally our model is to combine analysis resolution and expansion, but
--  this is the one case where this model falls down. Here is how we patch
--  it up without causing too much distortion to our basic model.

--  A switch (sede below) is set to indicate that we are in the initial
--  occurence of a default expression. The analyzer is then called on this
--  expression with the switch set true. Analysis and resolution proceed
--  almost as usual, except that Freeze_Expression will not freeze
--  non-static expressions if this switch is set, and the call to Expand at
--  the end of resolution is skipped. This also skips the code that normally
--  sets the Analyzed flag to True). The result is that when we are done the
--  tree is still marked as unanalyzed, but all types for static expressions
--  are frozen as required, and all entities of variables have been
--  recorded.  We then turn off the switch, and later on reanalyze the
--  expression with the switch off. The effect is that this second analysis
--  freezes the rest of the types as required, and generates code but
--  visibility analysis is not repeated since all the entities are marked.

--  The second analysis (the one that generates code) is in the context
--  where the code is required. For a record field default, this is in
--  the initialization procedure for the record and for a subprogram
--  default parameter, it is at the point the subprogram is frozen.
--  For a priority or storage size pragma it is in the context of the
--  Init_Proc for the task or protected object.

------------------
-- Pre-Analysis --
------------------

--  For certain kind of expressions, such as aggregates, we need to defer
--  expansion of the aggregate and its inner expressions after the whole
--  set of expressions appearing inside the aggregate have been analyzed.
--  Consider, for instance the following example:
--
--     (1 .. 100 => new Thing (Function_Call))
--
--  The normal Analysis-Resolution-Expansion mechanism where expansion
--  of the children is performed before expansion of the parent does not
--  work if the code generated for the children by the expander needs
--  to be evaluated repeatdly (for instance in the above aggregate
--  "new Thing (Function_Call)" needs to be called 100 times.)
--  The reason why this mecanism does not work is that, the expanded code
--  for the children is typically inserted above the parent and thus
--  when the father gets expanded no re-evaluation takes place. For instance
--  in the case of aggregates if "new Thing (Function_Call)" is expanded
--  before of the aggregate the expanded code will be placed outside
--  of the aggregate and when expanding the aggregate the loop from 1 to 100
--  will not surround the expanded code for "new Thing (Function_Call)".
--
--  To remedy this situation we introduce a new flag which signals whether
--  we want a full analysis (ie expansion is enabled) or a pre-analysis
--  which performs Analysis and Resolution but no expansion.
--
--  After the complete pre-analysis of an expression has been carried out
--  we can transform the expression and then carry out the full
--  Analyze-Resolve-Expand cycle on the transformed expression top-down
--  so that the expansion of inner expressions happens inside the newly
--  generated node for the parent expression.
--
--  Note that the difference between processing of default expressions and
--  pre-analysis of other expressions is that we do carry out freezing in
--  the latter but not in the former (except for static scalar expressions).
--  The routine that performs pre-analysis is called Pre_Analyze_And_Resolve
--  and is in Sem_Res.

with Alloc;
with Einfo;  use Einfo;
with Opt;    use Opt;
with Table;
with Types;  use Types;

package Sem is

   New_Nodes_OK : Int := 1;
   --  Temporary flag for use in checking out HLO. Set non-zero if it is
   --  OK to generate new nodes.

   -----------------------------
   -- Semantic Analysis Flags --
   -----------------------------

   Full_Analysis : Boolean := True;
   --  Switch to indicate whether we are doing a full analysis or a
   --  pre-analysis. In normal analysis mode (Analysis-Expansion for
   --  instructions or declarations) or (Analysis-Resolution-Expansion for
   --  expressions) this flag is set. Note that if we are not generating
   --  code the expansion phase merely sets the Analyzed flag to True in
   --  this case. If we are in Pre-Analysis mode (see above) this flag is
   --  set to False then the expansion phase is skipped.
   --  When this flag is False the flag Expander_Active is also False
   --  (the Expander_Activer flag defined in the spec of package Expander
   --  tells you whether expansion is currently enabled).
   --  You should really regard this as a read only flag.

   In_Default_Expression : Boolean := False;
   --  Switch to indicate that we are in a default expression, as described
   --  above. Note that this must be recursively saved on a Semantics call
   --  since it is possible for the analysis of an expression to result in
   --  a recursive call (e.g. to get the entity for System.Address as part
   --  of the processing of an Address attribute reference).
   --  When this switch is True then Full_Analysis above must be False.
   --  You should really regard this as a read only flag.

   In_Deleted_Code : Boolean := False;
   --  If the condition in an if-statement is statically known, the branch
   --  that is not taken is analyzed with expansion disabled, and the tree
   --  is deleted after analysis. Itypes generated in deleted code must be
   --  frozen from start, because the tree on which they depend will not
   --  be available at the freeze point.

   In_Inlined_Body : Boolean := False;
   --  Switch to indicate that we are analyzing and resolving an inlined
   --  body. Type checking is disabled in this context, because types are
   --  known to be compatible. This avoids problems with private types whose
   --  full view is derived from private types.

   Inside_A_Generic : Boolean := False;
   --  This flag is set if we are processing a generic specification,
   --  generic definition, or generic body. When this flag is True the
   --  Expander_Active flag is False to disable any code expansion (see
   --  package Expander). Only the generic processing can modify the
   --  status of this flag, any other client should regard it as read-only.

   Unloaded_Subunits : Boolean := False;
   --  This flag is set True if we have subunits that are not loaded. This
   --  occurs when the main unit is a subunit, and contains lower level
   --  subunits that are not loaded. We use this flag to suppress warnings
   --  about unused variables, since these warnings are unreliable in this
   --  case. We could perhaps do a more accurate job and retain some of the
   --  warnings, but it is quite a tricky job. See test 4323-002.

   -----------------
   -- Scope Stack --
   -----------------

   --  The scope stack indicates the declarative regions that are currently
   --  being processed (analyzed and/or expanded). The scope stack is one of
   --  basic visibility structures in the compiler: entities that are declared
   --  in a scope that is currently on the scope stack are immediately visible.
   --  (leaving aside issues of hiding and overloading).

   --  Initially, the scope stack only contains an entry for package Standard.
   --  When a compilation unit, subprogram unit, block or declarative region
   --  is being processed, the corresponding entity is pushed on the scope
   --  stack. It is removed after the processing step is completed. A given
   --  entity can be placed several times on the scope stack, for example
   --  when processing derived type declarations, freeze nodes, etc. The top
   --  of the scope stack is the innermost scope currently being processed.
   --  It is obtained through function Current_Scope. After a compilation unit
   --  has been processed, the scope stack must contain only Standard.
   --  The predicate In_Open_Scopes specifies whether a scope is currently
   --  on the scope stack.

   --  This model is complicated by the need to compile units on the fly, in
   --  the middle of the compilation of other units. This arises when compiling
   --  instantiations, and when compiling run-time packages obtained through
   --  rtsfind. Given that the scope stack is a single static and global
   --  structure (not originally designed for the recursive processing required
   --  by rtsfind for example) additional machinery is needed to indicate what
   --  is currently being compiled. As a result, the scope stack holds several
   --  contiguous sections that correspond to the compilation of a given
   --  compilation unit. These sections are separated by distinct occurrences
   --  of package Standard. The currently active section of the scope stack
   --  goes from the current scope to the first occurrence of Standard, which
   --  is additionally marked with the flag Is_Active_Stack_Base. The basic
   --  visibility routine (Find_Direct_Name, sem_ch8) uses this contiguous
   --  section of the scope stack to determine whether a given entity is or
   --  is not visible at a point. In_Open_Scopes only examines the currently
   --  active section of the scope stack.

   --  Similar complications arise when processing child instances. These
   --  must be compiled in the context of parent instances, and therefore the
   --  parents must be pushed on the stack before compiling the child, and
   --  removed afterwards. Routines Save_Scope_Stack and Restore_Scope_Stack
   --  are used to set/reset the visibility of entities declared in scopes
   --  that are currently on the scope stack, and are used when compiling
   --  instance bodies on the fly.

   --  It is clear in retrospect that all semantic processing and visibility
   --  structures should have been fully recursive. The rtsfind mechanism,
   --  and the complexities brought about by subunits and by generic child
   --  units and their instantitions, have led to a hybrid model that carries
   --  more state than one would wish.

   type Scope_Stack_Entry is record
      Entity : Entity_Id;
      --  Entity representing the scope

      Last_Subprogram_Name : String_Ptr;
      --  Pointer to name of last subprogram body in this scope. Used for
      --  testing proper alpha ordering of subprogram bodies in scope.

      Save_Scope_Suppress  : Suppress_Array;
      --  Save contents of Scope_Suppress on entry

      Save_Local_Entity_Suppress : Int;
      --  Save contents of Local_Entity_Suppress.Last on entry

      Is_Transient : Boolean;
      --  Marks Transient Scopes (See Exp_Ch7 body for details)

      Previous_Visibility : Boolean;
      --  Used when installing the parent(s) of the current compilation unit.
      --  The parent may already be visible because of an ongoing compilation,
      --  and the proper visibility must be restored on exit. The flag is
      --  typically needed when the context of a child unit requires
      --  compilation of a sibling. In other cases the flag is set to False.
      --  See Sem_Ch10 (Install_Parents, Remove_Parents).

      Node_To_Be_Wrapped : Node_Id;
      --  Only used in transient scopes. Records the node which will
      --  be wrapped by the transient block.

      Actions_To_Be_Wrapped_Before : List_Id;
      Actions_To_Be_Wrapped_After  : List_Id;
      --  Actions that have to be inserted at the start or at the end of a
      --  transient block. Used to temporarily hold these actions until the
      --  block is created, at which time the actions are moved to the block.

      Pending_Freeze_Actions : List_Id;
      --  Used to collect freeze entity nodes and associated actions that are
      --  generated in a inner context but need to be analyzed outside, such as
      --  records and initialization procedures. On exit from the scope, this
      --  list of actions is inserted before the scope construct and analyzed
      --  to generate the corresponding freeze processing and elaboration of
      --  other associated actions.

      First_Use_Clause : Node_Id;
      --  Head of list of Use_Clauses in current scope. The list is built when
      --  the declarations in the scope are processed. The list is traversed
      --  on scope exit to undo the effect of the use clauses.

      Component_Alignment_Default : Component_Alignment_Kind;
      --  Component alignment to be applied to any record or array types that
      --  are declared for which a specific component alignment pragma does not
      --  set the alignment.

      Is_Active_Stack_Base : Boolean;
      --  Set to true only when entering the scope for Standard_Standard from
      --  from within procedure Semantics. Indicates the base of the current
      --  active set of scopes. Needed by In_Open_Scopes to handle cases where
      --  Standard_Standard can be pushed anew on the scope stack to start a
      --  new active section (see comment above).

   end record;

   package Scope_Stack is new Table.Table (
     Table_Component_Type => Scope_Stack_Entry,
     Table_Index_Type     => Int,
     Table_Low_Bound      => 0,
     Table_Initial        => Alloc.Scope_Stack_Initial,
     Table_Increment      => Alloc.Scope_Stack_Increment,
     Table_Name           => "Sem.Scope_Stack");

   -----------------------------------
   -- Handling of Check Suppression --
   -----------------------------------

   --  There are two kinds of suppress checks: scope based suppress checks,
   --  and entity based suppress checks.

   --  Scope based suppress checks (from initial command line arguments,
   --  or from Suppress pragmas not including an entity name) are recorded
   --  in the Sem.Supress variable, and all that is necessary is to save the
   --  state of this variable on scope entry, and restore it on scope exit.

   --  Entity based suppress checks, from Suppress pragmas giving an Entity_Id,
   --  are handled as follows. If a suppress or unsuppress pragma is
   --  encountered for a given entity, then the flag Checks_May_Be_Suppressed
   --  is set in the entity and an entry is made in either the
   --  Local_Entity_Suppress table (case of pragma that appears in other than
   --  a package spec), or in the Global_Entity_Suppress table (case of pragma
   --  that appears in a package spec, which is by the rule of RM 11.5(7)
   --  applicable throughout the life of the entity).

   --  If the Checks_May_Be_Suppressed flag is set in an entity then the
   --  procedure is to search first the local and then the global suppress
   --  tables (the local one being searched in reverse order, i.e. last in
   --  searched first). The only other point is that we have to make sure
   --  that we have proper nested interaction between such specific pragmas
   --  and locally applied general pragmas applying to all entities. This
   --  is achieved by including in the Local_Entity_Suppress table dummy
   --  entries with an empty Entity field that are applicable to all entities.

   Scope_Suppress : Suppress_Array := Suppress_Options;
   --  This array contains the current scope based settings of the suppress
   --  switches. It is initialized from the options as shown, and then modified
   --  by pragma Suppress. On entry to each scope, the current setting is saved
   --  the scope stack, and then restored on exit from the scope. This record
   --  may be rapidly checked to determine the current status of a check if
   --  no specific entity is involved or if the specific entity involved is
   --  one for which no specific Suppress/Unsuppress pragma has been set (as
   --  indicated by the Checks_May_Be_Suppressed flag being set).

   --  This scheme is a little complex, but serves the purpose of enabling
   --  a very rapid check in the common case where no entity specific pragma
   --  applies, and gives the right result when such pragmas are used even
   --  in complex cases of nested Suppress and Unsuppress pragmas.

   type Entity_Check_Suppress_Record is record
      Entity : Entity_Id;
      --  Entity to which the check applies, or Empty for a local check
      --  that has no entity name (and thus applies to all entities).

      Check : Check_Id;
      --  Check which is set (note this cannot be All_Checks, if the All_Checks
      --  case, a sequence of eentries appears for the individual checks.

      Suppress : Boolean;
      --  Set True for Suppress, and False for Unsuppress
   end record;

   --  The Local_Entity_Suppress table is a stack, to which new entries are
   --  added for Suppress and Unsuppress pragmas appearing in other than
   --  package specs. Such pragmas are effective only to the end of the scope
   --  in which they appear. This is achieved by marking the stack on entry
   --  to a scope and then cutting back the stack to that marked point on
   --  scope exit.

   package Local_Entity_Suppress is new Table.Table (
     Table_Component_Type => Entity_Check_Suppress_Record,
     Table_Index_Type     => Int,
     Table_Low_Bound      => 0,
     Table_Initial        => Alloc.Entity_Suppress_Initial,
     Table_Increment      => Alloc.Entity_Suppress_Increment,
     Table_Name           => "Local_Entity_Suppress");

   --  The Global_Entity_Suppress table is used for entities which have
   --  a Suppress or Unsuppress pragma naming a specific entity in a
   --  package spec. Such pragmas always refer to entities in the package
   --  spec and are effective throughout the lifetime of the named entity.

   package Global_Entity_Suppress is new Table.Table (
     Table_Component_Type => Entity_Check_Suppress_Record,
     Table_Index_Type     => Int,
     Table_Low_Bound      => 0,
     Table_Initial        => Alloc.Entity_Suppress_Initial,
     Table_Increment      => Alloc.Entity_Suppress_Increment,
     Table_Name           => "Global_Entity_Suppress");

   -----------------
   -- Subprograms --
   -----------------

   procedure Initialize;
   --  Initialize internal tables

   procedure Lock;
   --  Lock internal tables before calling back end

   procedure Semantics (Comp_Unit : Node_Id);
   --  This procedure is called to perform semantic analysis on the specified
   --  node which is the N_Compilation_Unit node for the unit.

   procedure Analyze (N : Node_Id);
   procedure Analyze (N : Node_Id; Suppress : Check_Id);
   --  This is the recursive procedure which is applied to individual nodes
   --  of the tree, starting at the top level node (compilation unit node)
   --  and then moving down the tree in a top down traversal. It calls
   --  individual routines with names Analyze_xxx to analyze node xxx. Each
   --  of these routines is responsible for calling Analyze on the components
   --  of the subtree.
   --
   --  Note: In the case of expression components (nodes whose Nkind is in
   --  N_Subexpr), the call to Analyze does not complete the semantic analysis
   --  of the node, since the type resolution cannot be completed until the
   --  complete context is analyzed. The completion of the type analysis occurs
   --  in the corresponding Resolve routine (see Sem_Res).
   --
   --  Note: for integer and real literals, the analyzer sets the flag to
   --  indicate that the result is a static expression. If the expander
   --  generates a literal that does NOT correspond to a static expression,
   --  e.g. by folding an expression whose value is known at compile-time,
   --  but is not technically static, then the caller should reset the
   --  Is_Static_Expression flag after analyzing but before resolving.
   --
   --  If the Suppress argument is present, then the analysis is done
   --  with the specified check suppressed (can be All_Checks to suppress
   --  all checks).

   procedure Analyze_List (L : List_Id);
   procedure Analyze_List (L : List_Id; Suppress : Check_Id);
   --  Analyzes each element of a list. If the Suppress argument is present,
   --  then the analysis is done with the specified check suppressed (can
   --  be All_Checks to suppress all checks).

   procedure Copy_Suppress_Status
     (C    : Check_Id;
      From : Entity_Id;
      To   : Entity_Id);
   --  If From is an entity for which check C is explicitly suppressed
   --  then also explicitly suppress the corresponding check in To.

   procedure Insert_List_After_And_Analyze
     (N : Node_Id; L : List_Id);
   procedure Insert_List_After_And_Analyze
     (N : Node_Id; L : List_Id; Suppress : Check_Id);
   --  Inserts list L after node N using Nlists.Insert_List_After, and then,
   --  after this insertion is complete, analyzes all the nodes in the list,
   --  including any additional nodes generated by this analysis. If the list
   --  is empty or be No_List, the call has no effect. If the Suppress
   --  argument is present, then the analysis is done with the specified
   --  check suppressed (can be All_Checks to suppress all checks).

   procedure Insert_List_Before_And_Analyze
     (N : Node_Id; L : List_Id);
   procedure Insert_List_Before_And_Analyze
     (N : Node_Id; L : List_Id; Suppress : Check_Id);
   --  Inserts list L before node N using Nlists.Insert_List_Before, and then,
   --  after this insertion is complete, analyzes all the nodes in the list,
   --  including any additional nodes generated by this analysis. If the list
   --  is empty or be No_List, the call has no effect. If the Suppress
   --  argument is present, then the analysis is done with the specified
   --  check suppressed (can be All_Checks to suppress all checks).

   procedure Insert_After_And_Analyze
     (N : Node_Id; M : Node_Id);
   procedure Insert_After_And_Analyze
     (N : Node_Id; M : Node_Id; Suppress : Check_Id);
   --  Inserts node M after node N and then after the insertion is complete,
   --  analyzes the inserted node and all nodes that are generated by
   --  this analysis. If the node is empty, the call has no effect. If the
   --  Suppress argument is present, then the analysis is done with the
   --  specified check suppressed (can be All_Checks to suppress all checks).

   procedure Insert_Before_And_Analyze
     (N : Node_Id; M : Node_Id);
   procedure Insert_Before_And_Analyze
     (N : Node_Id; M : Node_Id; Suppress : Check_Id);
   --  Inserts node M before node N and then after the insertion is complete,
   --  analyzes the inserted node and all nodes that could be generated by
   --  this analysis. If the node is empty, the call has no effect. If the
   --  Suppress argument is present, then the analysis is done with the
   --  specified check suppressed (can be All_Checks to suppress all checks).

   function External_Ref_In_Generic (E : Entity_Id) return Boolean;
   --  Return True if we are in the context of a generic and E is
   --  external (more global) to it.

   procedure Enter_Generic_Scope (S : Entity_Id);
   --  Shall be called each time a Generic subprogram or package scope is
   --  entered.  S is the entity of the scope.
   --  ??? At the moment, only called for package specs because this mechanism
   --  is only used for avoiding freezing of external references in generics
   --  and this can only be an issue if the outer generic scope is a package
   --  spec (otherwise all external entities are already frozen)

   procedure Exit_Generic_Scope  (S : Entity_Id);
   --  Shall be called each time a Generic subprogram or package scope is
   --  exited.  S is the entity of the scope.
   --  ??? At the moment, only called for package specs exit.

   function Explicit_Suppress (E : Entity_Id; C : Check_Id) return Boolean;
   --  This function returns True if an explicit pragma Suppress for check C
   --  is present in the package defining E.

   function Is_Check_Suppressed (E : Entity_Id; C : Check_Id) return Boolean;
   --  This function is called if Checks_May_Be_Suppressed (E) is True to
   --  determine whether check C is suppressed either on the entity E or
   --  as the result of a scope suppress pragma. If Checks_May_Be_Suppressed
   --  is False, then the status of the check can be determined simply by
   --  examining Scope_Checks (C), so this routine is not called in that case.

end Sem;