home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gnat-2.06-src.tgz / tar.out / fsf / gnat / ada / sem.ads < prev    next >
Text File  |  1996-09-28  |  15KB  |  303 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT COMPILER COMPONENTS                         --
  4. --                                                                          --
  5. --                                  S E M                                   --
  6. --                                                                          --
  7. --                                 S p e c                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.77 $                             --
  10. --                                                                          --
  11. --        Copyright (c) 1992,1993,1994,1995 NYU, All Rights Reserved        --
  12. --                                                                          --
  13. -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  14. -- terms of the  GNU General Public License as published  by the Free Soft- --
  15. -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
  16. -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  17. -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  18. -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
  19. -- for  more details.  You should have  received  a copy of the GNU General --
  20. -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
  21. -- to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. --
  22. --                                                                          --
  23. ------------------------------------------------------------------------------
  24.  
  25. with Opt;    use Opt;
  26. with Snames; use Snames;
  27. with Table;
  28. with Types;  use Types;
  29.  
  30. package Sem is
  31.  
  32.    Subunit_Found : exception;
  33.    --  This exception is used when the main unit is a subunit, and the current
  34.    --  unit is one of its parents. In this case the parent is being analyzed
  35.    --  only to provide the necessary context for the subunit, so as soon as
  36.    --  the subunit has been analyzed, there is no need to continue with the
  37.    --  analysis of the parent, so this exception is raised to get out.
  38.  
  39.    -------------------------------------
  40.    -- Handling of Default Expressions --
  41.    -------------------------------------
  42.  
  43.    --  The default expressions in component declarations and in procedure
  44.    --  specifications (but not the ones in object declarations) are quite
  45.    --  tricky to handle. The problem is that some processing is required
  46.    --  at the point where the expression appears:
  47.    --
  48.    --    visibility analysis (including user defined operators)
  49.    --    freezing of static expressions
  50.    --
  51.    --  but other processing must be deferred until the enclosing entity
  52.    --  (record or procedure specification) is frozen:
  53.    --
  54.    --    freezing of any other types in the expression
  55.    --    generation of code
  56.    --
  57.    --  Code generation has to be deferred since you can't generate code for
  58.    --  expressions that refernce types that have not been frozen yet. Although
  59.    --  the generation of code at the machine level is deferred to Gigi and GCC
  60.    --  processing, our expander does a lot of code generation activity. As an
  61.    --  example, consider the following:
  62.    --
  63.    --      type x is delta 0.5 range -10.0 .. +10.0;
  64.    --      ...
  65.    --      type q is record
  66.    --        xx : x := y * z;
  67.    --      end record;
  68.    --
  69.    --      for x'small use 0.25
  70.    --
  71.    --  The expander is in charge of dealing with fixed-point, and of course
  72.    --  the small declaration, which is not too late, since the declaration of
  73.    --  type q does *not* freeze type x, definitely affects the expanded code.
  74.    --
  75.    --  Generally our model is to combine analysis and expansion, but this is
  76.    --  the one case where this model falls down. Here is how we patch it up
  77.    --  without causing too much distortion to our basic model.
  78.    --
  79.    --  A switch is set to indicate that we are in the initial occurence of
  80.    --  a default expression. The analyzer is then called on this expression
  81.    --  with the switch set true. Analysis and resolution proceed almost as
  82.    --  usual, except that Freeze_Expression will not freeze non-static
  83.    --  expressions if this switch is set, and the call to Expand at the end
  84.    --  of resolution is skipped. This also skips the code that normally sets
  85.    --  the Analyzed flag to True). The result is that when we are done the tree
  86.    --  is still marked as unanalyzed, but all types for static expressions are
  87.    --  frozen as required, and all entities of variables have been recorded.
  88.    --  We then turn off the switch, and later on reanalyze the expression with
  89.    --  the switch off. The effect is that this second analysis freezes the rest
  90.    --  of the types as required, and generates code but visibility analysis is
  91.    --  not repeated since all the entities are marked.
  92.  
  93.    In_Default_Expression : Boolean := False;
  94.    --  Switch to indicate that we are in a default expression, as described
  95.    --  above. Note that this must be recursively saved on a Semantics call
  96.    --  since it is possible for the analysis of an expression to result in
  97.    --  a recursive call (e.g. to get the entity for System.Address as part
  98.    --  of the processing of an Address attribute reference).
  99.  
  100.    -----------------
  101.    -- Scope Stack --
  102.    -----------------
  103.  
  104.    Scope_Suppress : Suppress_Record := Suppress_Options;
  105.    --  This record contains the current scope based settings of the suppress
  106.    --  switches. It is initialized from the options as shown, and then modified
  107.    --  by pragma Suppress. On entry to each scope, the current setting is saved
  108.    --  the scope stack, and then restored on exit from the scope.
  109.  
  110.    --  The scope stack holds all entries of the scope table. As in the parser,
  111.    --  we use Last as the stack pointer, so that we can always find the scope
  112.    --  that is currently open in Scope_Stack.Table (Scope_Stack.Last). The
  113.    --  oldest entry, at Scope_Stack (0) is Standard. The entries in the table
  114.    --  include the entity for the referenced scope, together with information
  115.    --  used to restore the proper setting of check suppressions on scope exit.
  116.  
  117.    --  There are two kinds of suppress checks, scope based suppress checks
  118.    --  (from initial command line arguments, or from Suppress pragmas not
  119.    --  including an entity name). The scope based suppress checks are recorded
  120.    --  in the Sem.Supress variable, and all that is necessary is to save the
  121.    --  state of this variable on scope entry, and restore it on scope exit.
  122.  
  123.    --  The other kind of suppress check is entity based suppress checks, from
  124.    --  Suppress pragmas giving an Entity_Id. These checks are reflected by the
  125.    --  appropriate bit being set in the corresponding entity, and restoring the
  126.    --  setting of these bits is a little trickier. In particular a given pragma
  127.    --  Suppress may or may not affect the current state. If it sets a check for
  128.    --  an entity that is already checked, then it is important that this check
  129.    --  not be restored on scope exit. The situation is made more complicated
  130.    --  by the fact that a given suppress pragma can specify multiple entities
  131.    --  (in the overloaded case), and multiple checks (by using All_Checks), so
  132.    --  that it may be partially effective. On exit only checks that were in
  133.    --  fact effective must be removed. Logically we could do this by saving
  134.    --  the entire state of the entity flags on scope entry and restoring them
  135.    --  on scope exit, but that would be ludicrous, so what we do instead is to
  136.    --  maintain the following differential structure that shows what checks
  137.    --  were installed for the current scope.
  138.  
  139.    --  Note: Suppress pragmas that specify entities defined in a package
  140.    --  spec do not make entries in this table, since such checks suppress
  141.    --  requests are valid for the entire life of the entity.
  142.  
  143.    type Entity_Check_Suppress_Record is record
  144.       Entity : Entity_Id;
  145.       --  Entity to which the check applies
  146.  
  147.       Check : Check_Id;
  148.       --  Check which is set (note this cannot be All_Checks, if the All_Checks
  149.       --  case, a sequence of eentries appears for the individual checks.
  150.    end record;
  151.  
  152.    --  Entity_Suppress is a stack, to which new entries are added as they
  153.    --  are processed (see pragma Suppress circuit in Sem_Prag). The scope
  154.    --  stack entry simply saves the stack pointer on entry, and restores
  155.    --  it on exit by reversing the checks one by one.
  156.  
  157.    package Entity_Suppress is new Table (
  158.      Table_Component_Type => Entity_Check_Suppress_Record,
  159.      Table_Index_Type     => Int,
  160.      Table_Low_Bound      => 0,
  161.      Table_Initial        => 1000,
  162.      Table_Increment      => 100,
  163.      Table_Name           => "Sem.Entity_Suppress");
  164.  
  165.    --  Here is the scope stack itself
  166.  
  167.    type Scope_Stack_Entry is record
  168.       Entity : Entity_Id;
  169.       --  Entity representing the scope
  170.  
  171.       Save_Scope_Suppress  : Suppress_Record;
  172.       --  Save contents of Scope_Suppress on entry
  173.  
  174.       Save_Entity_Suppress : Int;
  175.       --  Save contents of Entity_Suppress.Last on entry
  176.  
  177.       Is_Transient : Boolean;
  178.       --  Marks Transient Scopes (See Exp_Ch7 body for details)
  179.  
  180.       Node_To_Be_Wrapped : Node_Id;
  181.       --  Only used in transient scopes. Records the node which will
  182.       --  be wrapped by the transient block.
  183.  
  184.       Actions_To_Be_Wrapped : List_Id;
  185.       --  Actions that have to be inserted at the start of a transient
  186.       --  block. Used to temporarily hold these actions until the block
  187.       --  is created, at which time the actions are moved to the block.
  188.  
  189.       Pending_Freeze_Nodes : List_Id;
  190.       --  Used to collect freeze entity nodes that are generated in a inner
  191.       --  context but need to be analyzed outside, such as records and
  192.       --  initialization procedures. On exit from the scope, this list of
  193.       --  freeze entity nodes is inserted before the scope construct and
  194.       --  analyzed to generate the corresponding freeze actions.
  195.  
  196.       First_Use_Clause : Node_Id;
  197.       --  Head of list of Use_Clauses in current scope. The list is built
  198.       --  when the declarations in the scope are processed. The list is
  199.       --  traversed on scope exit to undo the effect of the use clauses.
  200.  
  201.    end record;
  202.  
  203.    package Scope_Stack is new Table (
  204.      Table_Component_Type => Scope_Stack_Entry,
  205.      Table_Index_Type     => Int,
  206.      Table_Low_Bound      => 0,
  207.      Table_Initial        => 50,
  208.      Table_Increment      => 100,
  209.      Table_Name           => "Sem.Scope_Stack");
  210.  
  211.    function Get_Scope_Suppress (C : Check_Id) return Boolean;
  212.    --  Get suppress status of check C for the current scope
  213.  
  214.    procedure Set_Scope_Suppress (C : Check_Id; B : Boolean);
  215.    --  Set suppress status of check C for the current scope
  216.  
  217.    -----------------
  218.    -- Subprograms --
  219.    -----------------
  220.  
  221.    procedure Semantics (Comp_Unit : Node_Id);
  222.    --  This procedure is called to perform semantic analysis on the specified
  223.    --  node which is the N_Compilation_Unit node for the unit.
  224.  
  225.    procedure Analyze (N : Node_Id);
  226.    procedure Analyze (N : Node_Id; Suppress : Check_Id);
  227.    --  This is the recursive procedure which is applied to individual nodes
  228.    --  of the tree, starting at the top level node (compilation unit node)
  229.    --  and then moving down the tree in a top down traversal. It calls
  230.    --  individual routines with names Analyze_xxx to analyze node xxx. Each
  231.    --  of these routines is responsible for calling Analyze on the components
  232.    --  of the subtree.
  233.    --
  234.    --  Note: In the case of expression components (nodes whose Nkind is in
  235.    --  N_Subexpr), the call to Analyze does not complete the semantic analysis
  236.    --  of the node, since the type resolution cannot be completed until the
  237.    --  complete context is analyzed. The completion of the type analysis occurs
  238.    --  in the corresponding Resolve routine (see Sem_Res).
  239.    --
  240.    --  Note: for integer and real literals, the analyzer sets the flag to
  241.    --  indicate that the result is a static expression. If the expander
  242.    --  generates a literal that does NOT correspond to a static expression,
  243.    --  e.g. by folding an expression whose value is known at compile-time,
  244.    --  but is not technically static, then the caller should reset the
  245.    --  Is_Static_Expression flag after analyzing but before resolving.
  246.    --
  247.    --  If the Suppress argument is present, then the analysis is done
  248.    --  with the specified check suppressed (can be All_Checks to suppress
  249.    --  all checks).
  250.  
  251.    procedure Analyze_List (L : List_Id);
  252.    procedure Analyze_List (L : List_Id; Suppress : Check_Id);
  253.    --  Analyzes each element of a list. If the Suppress argument is present,
  254.    --  then the analysis is done with the specified check suppressed (can
  255.    --  be All_Checks to suppress all checks).
  256.  
  257.    procedure Insert_List_After_And_Analyze
  258.      (N : Node_Id; L : List_Id);
  259.    procedure Insert_List_After_And_Analyze
  260.      (N : Node_Id; L : List_Id; Suppress : Check_Id);
  261.    --  Inserts list L after node N using Nlists.Insert_List_After, and then,
  262.    --  after this insertion is complete, analyzes all the nodes in the list,
  263.    --  including any additional nodes generated by this analysis. If the list
  264.    --  is empty or be No_List, the call has no effect. If the Suppress
  265.    --  argument is present, then the analysis is done with the specified
  266.    --  check suppressed (can be All_Checks to suppress all checks).
  267.  
  268.    --  Same as Insert_List_After_And_Analyze, with specified check
  269.    --  suppressed (can be All_Checks).
  270.  
  271.    procedure Insert_List_Before_And_Analyze
  272.      (N : Node_Id; L : List_Id);
  273.    procedure Insert_List_Before_And_Analyze
  274.      (N : Node_Id; L : List_Id; Suppress : Check_Id);
  275.    --  Inserts list L before node N using Nlists.Insert_List_Before, and then,
  276.    --  after this insertion is complete, analyzes all the nodes in the list,
  277.    --  including any additional nodes generated by this analysis. If the list
  278.    --  is empty or be No_List, the call has no effect. If the Suppress
  279.    --  argument is present, then the analysis is done with the specified
  280.    --  check suppressed (can be All_Checks to suppress all checks).
  281.  
  282.    procedure Insert_After_And_Analyze
  283.      (N : Node_Id; M : Node_Id);
  284.    procedure Insert_After_And_Analyze
  285.      (N : Node_Id; M : Node_Id; Suppress : Check_Id);
  286.    --  Inserts node M after node N and then after the insertion is complete,
  287.    --  analyzes the inserted node and all nodes that are generated by
  288.    --  this analysis. If the node is empty, the call has no effect. If the
  289.    --  Suppress argument is present, then the analysis is done with the
  290.    --  specified check suppressed (can be All_Checks to suppress all checks).
  291.  
  292.    procedure Insert_Before_And_Analyze
  293.      (N : Node_Id; M : Node_Id);
  294.    procedure Insert_Before_And_Analyze
  295.      (N : Node_Id; M : Node_Id; Suppress : Check_Id);
  296.    --  Inserts node M before node N and then after the insertion is complete,
  297.    --  analyzes the inserted node and all nodes that could be generated by
  298.    --  this analysis. If the node is empty, the call has no effect. If the
  299.    --  Suppress argument is present, then the analysis is done with the
  300.    --  specified check suppressed (can be All_Checks to suppress all checks).
  301.  
  302. end Sem;
  303.