diff options
Diffstat (limited to 'gcc-4.2.1/gcc/ada/sem.ads')
-rw-r--r-- | gcc-4.2.1/gcc/ada/sem.ads | 555 |
1 files changed, 0 insertions, 555 deletions
diff --git a/gcc-4.2.1/gcc/ada/sem.ads b/gcc-4.2.1/gcc/ada/sem.ads deleted file mode 100644 index d7fb9a649..000000000 --- a/gcc-4.2.1/gcc/ada/sem.ads +++ /dev/null @@ -1,555 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- S E M -- --- -- --- S p e c -- --- -- --- Copyright (C) 1992-2005, 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 -- - ----------------------------- - - Explicit_Overriding : Boolean := False; - -- Switch to indicate whether checking mechanism described in AI-218 - -- is enforced: subprograms that override inherited operations must be - -- be marked explicitly, to prevent accidental or omitted overriding. - - 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 holds all entries of the scope table. As in the parser, - -- we use Last as the stack pointer, so that we can always find the scope - -- that is currently open in Scope_Stack.Table (Scope_Stack.Last). The - -- oldest entry, at Scope_Stack (0) is Standard. The entries in the table - -- include the entity for the referenced scope, together with information - -- used to restore the proper setting of check suppressions on scope exit. - - 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. - - 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 in the middle of the active - -- set of scopes (occurs for instantiations of generic child units). - 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 chems (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; |