OSDN Git Service

2009-10-30 Emmanuel Briot <briot@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / sem_scil.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                             S E M _ S C I L                              --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --             Copyright (C) 2009, Free Software Foundation, Inc.           --
10 --                                                                          --
11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
12 -- terms of the  GNU General Public License as published  by the Free Soft- --
13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
17 -- for  more details.  You should have  received  a copy of the GNU General --
18 -- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license.          --
20 --                                                                          --
21 -- GNAT was originally developed  by the GNAT team at  New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
23 --                                                                          --
24 ------------------------------------------------------------------------------
25
26 with Einfo;    use Einfo;
27 with Namet;    use Namet;
28 with Nlists;   use Nlists;
29 with Opt;      use Opt;
30 with Rtsfind;  use Rtsfind;
31 with Sem;      use Sem;
32 with Sem_Aux;  use Sem_Aux;
33 with Sem_Util; use Sem_Util;
34 with Sinfo;    use Sinfo;
35 with Snames;   use Snames;
36 with Stand;    use Stand;
37
38 package body Sem_SCIL is
39
40    ----------------------
41    -- Adjust_SCIL_Node --
42    ----------------------
43
44    procedure Adjust_SCIL_Node (Old_Node : Node_Id; New_Node : Node_Id) is
45       SCIL_Node : Node_Id;
46
47    begin
48       pragma Assert (Generate_SCIL);
49
50       --  Check cases in which no action is required. Currently the only SCIL
51       --  nodes that may require adjustment are those of dispatching calls
52       --  internally generated by the frontend.
53
54       if Comes_From_Source (Old_Node)
55         or else not
56           Nkind_In (New_Node, N_Function_Call, N_Procedure_Call_Statement)
57       then
58          return;
59
60       --  Conditional expression associated with equality operator. Old_Node
61       --  may be part of the expansion of the predefined equality operator of
62       --  a tagged type and hence we need to check if it has a SCIL dispatching
63       --  node that needs adjustment.
64
65       elsif Nkind (Old_Node) = N_Conditional_Expression
66         and then (Nkind (Original_Node (Old_Node)) = N_Op_Eq
67                     or else
68                       (Nkind (Original_Node (Old_Node)) = N_Function_Call
69                         and then Chars (Name (Original_Node (Old_Node))) =
70                                                                  Name_Op_Eq))
71       then
72          null;
73
74       --  Type conversions may involve dispatching calls to functions whose
75       --  associated SCIL dispatching node needs adjustment.
76
77       elsif Nkind (Old_Node) = N_Type_Conversion then
78          null;
79
80       --  Relocated subprogram call
81
82       elsif Nkind (Old_Node) = Nkind (New_Node)
83         and then Original_Node (Old_Node) = Original_Node (New_Node)
84       then
85          null;
86
87       else
88          return;
89       end if;
90
91       --  Search for the SCIL node and update it (if found)
92
93       SCIL_Node := Find_SCIL_Node (Old_Node);
94
95       if Present (SCIL_Node) then
96          Set_SCIL_Related_Node (SCIL_Node, New_Node);
97       end if;
98    end Adjust_SCIL_Node;
99
100    ---------------------
101    -- Check_SCIL_Node --
102    ---------------------
103
104    --  Is this a good name for the function, given it only deals with
105    --  N_SCIL_Dispatching_Call case ???
106
107    function Check_SCIL_Node (N : Node_Id) return Traverse_Result is
108       Ctrl_Tag : Node_Id;
109       Ctrl_Typ : Entity_Id;
110
111    begin
112       if Nkind (N) = N_SCIL_Dispatching_Call then
113          Ctrl_Tag := SCIL_Controlling_Tag (N);
114
115          --  SCIL_Related_Node of SCIL dispatching call nodes MUST reference
116          --  subprogram calls.
117
118          if not Nkind_In (SCIL_Related_Node (N), N_Function_Call,
119                                                  N_Procedure_Call_Statement)
120          then
121             pragma Assert (False);
122             raise Program_Error;
123
124          --  In simple cases the controlling tag is the tag of the controlling
125          --  argument (i.e. Obj.Tag).
126
127          elsif Nkind (Ctrl_Tag) = N_Selected_Component then
128             Ctrl_Typ := Etype (Ctrl_Tag);
129
130             --  Interface types are unsupported
131
132             if Is_Interface (Ctrl_Typ)
133               or else (RTE_Available (RE_Interface_Tag)
134                          and then Ctrl_Typ = RTE (RE_Interface_Tag))
135             then
136                null;
137
138             else
139                pragma Assert (Ctrl_Typ = RTE (RE_Tag));
140                null;
141             end if;
142
143          --  When the controlling tag of a dispatching call is an identifier
144          --  the SCIL_Controlling_Tag attribute references the corresponding
145          --  object or parameter declaration. Interface types are still
146          --  unsupported.
147
148          elsif Nkind_In (Ctrl_Tag, N_Object_Declaration,
149                                    N_Parameter_Specification)
150          then
151             Ctrl_Typ := Etype (Defining_Identifier (Ctrl_Tag));
152
153             --  Interface types are unsupported.
154
155             if Is_Interface (Ctrl_Typ)
156               or else (RTE_Available (RE_Interface_Tag)
157                         and then Ctrl_Typ = RTE (RE_Interface_Tag))
158               or else (Is_Access_Type (Ctrl_Typ)
159                         and then
160                           Is_Interface
161                             (Available_View
162                               (Base_Type (Designated_Type (Ctrl_Typ)))))
163             then
164                null;
165
166             else
167                pragma Assert
168                  (Ctrl_Typ = RTE (RE_Tag)
169                     or else
170                       (Is_Access_Type (Ctrl_Typ)
171                         and then Available_View
172                                   (Base_Type (Designated_Type (Ctrl_Typ))) =
173                                                                 RTE (RE_Tag)));
174                null;
175             end if;
176
177          --  Interface types are unsupported
178
179          elsif Is_Interface (Etype (Ctrl_Tag)) then
180             null;
181
182          else
183             pragma Assert (False);
184             raise Program_Error;
185          end if;
186
187          return Skip;
188
189       --  Node is not N_SCIL_Dispatching_Call
190
191       else
192          return OK;
193       end if;
194    end Check_SCIL_Node;
195
196    --------------------
197    -- Find_SCIL_Node --
198    --------------------
199
200    function Find_SCIL_Node (Node : Node_Id) return Node_Id is
201       Found_Node : Node_Id;
202       --  This variable stores the last node found by the nested subprogram
203       --  Find_SCIL_Node.
204
205       function Find_SCIL_Node (L : List_Id) return Boolean;
206       --  Searches in list L for a SCIL node associated with a dispatching call
207       --  whose SCIL_Related_Node is Node. If found returns true and stores the
208       --  SCIL node in Found_Node; otherwise returns False and sets Found_Node
209       --  to Empty.
210
211       --------------------
212       -- Find_SCIL_Node --
213       --------------------
214
215       function Find_SCIL_Node (L : List_Id) return Boolean is
216          N : Node_Id;
217
218       begin
219          N := First (L);
220          while Present (N) loop
221             if Nkind (N) in N_SCIL_Node
222               and then SCIL_Related_Node (N) = Node
223             then
224                Found_Node := N;
225                return True;
226             end if;
227
228             Next (N);
229          end loop;
230
231          Found_Node := Empty;
232          return False;
233       end Find_SCIL_Node;
234
235       --  Local variables
236
237       P : Node_Id;
238
239    --  Start of processing for Find_SCIL_Node
240
241    begin
242       pragma Assert (Generate_SCIL);
243
244       --  Search for the SCIL node in list associated with a transient scope
245
246       if Scope_Is_Transient then
247          declare
248             SE : Scope_Stack_Entry
249                    renames Scope_Stack.Table (Scope_Stack.Last);
250          begin
251             if SE.Is_Transient
252               and then Present (SE.Actions_To_Be_Wrapped_Before)
253               and then Find_SCIL_Node (SE.Actions_To_Be_Wrapped_Before)
254             then
255                return Found_Node;
256             end if;
257          end;
258       end if;
259
260       --  Otherwise climb up the tree searching for the SCIL node analyzing
261       --  all the lists in which Insert_Actions may have inserted it
262
263       P := Node;
264       while Present (P) loop
265          case Nkind (P) is
266
267             --  Actions associated with AND THEN or OR ELSE
268
269             when N_Short_Circuit =>
270                if Present (Actions (P))
271                  and then Find_SCIL_Node (Actions (P))
272                then
273                   return Found_Node;
274                end if;
275
276             --  Actions of conditional expressions
277
278             when N_Conditional_Expression =>
279                if (Present (Then_Actions (P))
280                     and then Find_SCIL_Node (Actions (P)))
281                  or else
282                   (Present (Else_Actions (P))
283                     and then Find_SCIL_Node (Else_Actions (P)))
284                then
285                   return Found_Node;
286                end if;
287
288             --  Actions in handled sequence of statements
289
290             when
291                N_Handled_Sequence_Of_Statements =>
292                   if Find_SCIL_Node (Statements (P)) then
293                      return Found_Node;
294                   end if;
295
296             --  Conditions of while expression or elsif.
297
298             when N_Iteration_Scheme |
299                  N_Elsif_Part
300             =>
301                if Present (Condition_Actions (P))
302                  and then Find_SCIL_Node (Condition_Actions (P))
303                then
304                   return Found_Node;
305                end if;
306
307             --  Statements, declarations, pragmas, representation clauses
308
309             when
310                --  Statements
311
312                N_Procedure_Call_Statement               |
313                N_Statement_Other_Than_Procedure_Call    |
314
315                --  Pragmas
316
317                N_Pragma                                 |
318
319                --  Representation_Clause
320
321                N_At_Clause                              |
322                N_Attribute_Definition_Clause            |
323                N_Enumeration_Representation_Clause      |
324                N_Record_Representation_Clause           |
325
326                --  Declarations
327
328                N_Abstract_Subprogram_Declaration        |
329                N_Entry_Body                             |
330                N_Exception_Declaration                  |
331                N_Exception_Renaming_Declaration         |
332                N_Formal_Abstract_Subprogram_Declaration |
333                N_Formal_Concrete_Subprogram_Declaration |
334                N_Formal_Object_Declaration              |
335                N_Formal_Type_Declaration                |
336                N_Full_Type_Declaration                  |
337                N_Function_Instantiation                 |
338                N_Generic_Function_Renaming_Declaration  |
339                N_Generic_Package_Declaration            |
340                N_Generic_Package_Renaming_Declaration   |
341                N_Generic_Procedure_Renaming_Declaration |
342                N_Generic_Subprogram_Declaration         |
343                N_Implicit_Label_Declaration             |
344                N_Incomplete_Type_Declaration            |
345                N_Number_Declaration                     |
346                N_Object_Declaration                     |
347                N_Object_Renaming_Declaration            |
348                N_Package_Body                           |
349                N_Package_Body_Stub                      |
350                N_Package_Declaration                    |
351                N_Package_Instantiation                  |
352                N_Package_Renaming_Declaration           |
353                N_Private_Extension_Declaration          |
354                N_Private_Type_Declaration               |
355                N_Procedure_Instantiation                |
356                N_Protected_Body                         |
357                N_Protected_Body_Stub                    |
358                N_Protected_Type_Declaration             |
359                N_Single_Task_Declaration                |
360                N_Subprogram_Body                        |
361                N_Subprogram_Body_Stub                   |
362                N_Subprogram_Declaration                 |
363                N_Subprogram_Renaming_Declaration        |
364                N_Subtype_Declaration                    |
365                N_Task_Body                              |
366                N_Task_Body_Stub                         |
367                N_Task_Type_Declaration                  |
368
369                --  Freeze entity behaves like a declaration or statement
370
371                N_Freeze_Entity
372             =>
373                --  Do not search here if the item is not a list member
374
375                if not Is_List_Member (P) then
376                   null;
377
378                --  Do not search if parent of P is an N_Component_Association
379                --  node (i.e. we are in the context of an N_Aggregate or
380                --  N_Extension_Aggregate node). In this case the node should
381                --  have been added before the entire aggregate.
382
383                elsif Nkind (Parent (P)) = N_Component_Association then
384                   null;
385
386                --  Do not search if the parent of P is either an N_Variant
387                --  node or an N_Record_Definition node. In this case the node
388                --  should have been added before the entire record.
389
390                elsif Nkind (Parent (P)) = N_Variant
391                  or else Nkind (Parent (P)) = N_Record_Definition
392                then
393                   null;
394
395                --  Otherwise search it in the list containing this node
396
397                elsif Find_SCIL_Node (List_Containing (P)) then
398                   return Found_Node;
399                end if;
400
401             --  A special case, N_Raise_xxx_Error can act either as a statement
402             --  or a subexpression. We diferentiate them by looking at the
403             --  Etype. It is set to Standard_Void_Type in the statement case.
404
405             when
406                N_Raise_xxx_Error =>
407                   if Etype (P) = Standard_Void_Type then
408                      if Is_List_Member (P)
409                        and then Find_SCIL_Node (List_Containing (P))
410                      then
411                         return Found_Node;
412                      end if;
413
414                   --  In the subexpression case, keep climbing
415
416                   else
417                      null;
418                   end if;
419
420             --  If a component association appears within a loop created for
421             --  an array aggregate, check if the SCIL node was added to the
422             --  the list of nodes attached to the association.
423
424             when
425                N_Component_Association =>
426                   if Nkind (Parent (P)) = N_Aggregate
427                     and then Present (Loop_Actions (P))
428                     and then Find_SCIL_Node (Loop_Actions (P))
429                   then
430                      return Found_Node;
431                   end if;
432
433             --  Another special case, an attribute denoting a procedure call
434
435             when
436                N_Attribute_Reference =>
437                   if Is_Procedure_Attribute_Name (Attribute_Name (P))
438                     and then Find_SCIL_Node (List_Containing (P))
439                   then
440                      return Found_Node;
441
442                   --  In the subexpression case, keep climbing
443
444                   else
445                      null;
446                   end if;
447
448             --  SCIL nodes do not have subtrees and hence they can never be
449             --  found climbing tree
450
451             when
452                N_SCIL_Dispatch_Table_Object_Init        |
453                N_SCIL_Dispatch_Table_Tag_Init           |
454                N_SCIL_Dispatching_Call                  |
455                N_SCIL_Tag_Init
456             =>
457                pragma Assert (False);
458                raise Program_Error;
459
460             --  For all other node types, keep climbing tree
461
462             when
463                N_Abortable_Part                         |
464                N_Accept_Alternative                     |
465                N_Access_Definition                      |
466                N_Access_Function_Definition             |
467                N_Access_Procedure_Definition            |
468                N_Access_To_Object_Definition            |
469                N_Aggregate                              |
470                N_Allocator                              |
471                N_Case_Statement_Alternative             |
472                N_Character_Literal                      |
473                N_Compilation_Unit                       |
474                N_Compilation_Unit_Aux                   |
475                N_Component_Clause                       |
476                N_Component_Declaration                  |
477                N_Component_Definition                   |
478                N_Component_List                         |
479                N_Constrained_Array_Definition           |
480                N_Decimal_Fixed_Point_Definition         |
481                N_Defining_Character_Literal             |
482                N_Defining_Identifier                    |
483                N_Defining_Operator_Symbol               |
484                N_Defining_Program_Unit_Name             |
485                N_Delay_Alternative                      |
486                N_Delta_Constraint                       |
487                N_Derived_Type_Definition                |
488                N_Designator                             |
489                N_Digits_Constraint                      |
490                N_Discriminant_Association               |
491                N_Discriminant_Specification             |
492                N_Empty                                  |
493                N_Entry_Body_Formal_Part                 |
494                N_Entry_Call_Alternative                 |
495                N_Entry_Declaration                      |
496                N_Entry_Index_Specification              |
497                N_Enumeration_Type_Definition            |
498                N_Error                                  |
499                N_Exception_Handler                      |
500                N_Expanded_Name                          |
501                N_Explicit_Dereference                   |
502                N_Extension_Aggregate                    |
503                N_Floating_Point_Definition              |
504                N_Formal_Decimal_Fixed_Point_Definition  |
505                N_Formal_Derived_Type_Definition         |
506                N_Formal_Discrete_Type_Definition        |
507                N_Formal_Floating_Point_Definition       |
508                N_Formal_Modular_Type_Definition         |
509                N_Formal_Ordinary_Fixed_Point_Definition |
510                N_Formal_Package_Declaration             |
511                N_Formal_Private_Type_Definition         |
512                N_Formal_Signed_Integer_Type_Definition  |
513                N_Function_Call                          |
514                N_Function_Specification                 |
515                N_Generic_Association                    |
516                N_Identifier                             |
517                N_In                                     |
518                N_Index_Or_Discriminant_Constraint       |
519                N_Indexed_Component                      |
520                N_Integer_Literal                        |
521                N_Itype_Reference                        |
522                N_Label                                  |
523                N_Loop_Parameter_Specification           |
524                N_Mod_Clause                             |
525                N_Modular_Type_Definition                |
526                N_Not_In                                 |
527                N_Null                                   |
528                N_Op_Abs                                 |
529                N_Op_Add                                 |
530                N_Op_And                                 |
531                N_Op_Concat                              |
532                N_Op_Divide                              |
533                N_Op_Eq                                  |
534                N_Op_Expon                               |
535                N_Op_Ge                                  |
536                N_Op_Gt                                  |
537                N_Op_Le                                  |
538                N_Op_Lt                                  |
539                N_Op_Minus                               |
540                N_Op_Mod                                 |
541                N_Op_Multiply                            |
542                N_Op_Ne                                  |
543                N_Op_Not                                 |
544                N_Op_Or                                  |
545                N_Op_Plus                                |
546                N_Op_Rem                                 |
547                N_Op_Rotate_Left                         |
548                N_Op_Rotate_Right                        |
549                N_Op_Shift_Left                          |
550                N_Op_Shift_Right                         |
551                N_Op_Shift_Right_Arithmetic              |
552                N_Op_Subtract                            |
553                N_Op_Xor                                 |
554                N_Operator_Symbol                        |
555                N_Ordinary_Fixed_Point_Definition        |
556                N_Others_Choice                          |
557                N_Package_Specification                  |
558                N_Parameter_Association                  |
559                N_Parameter_Specification                |
560                N_Pop_Constraint_Error_Label             |
561                N_Pop_Program_Error_Label                |
562                N_Pop_Storage_Error_Label                |
563                N_Pragma_Argument_Association            |
564                N_Procedure_Specification                |
565                N_Protected_Definition                   |
566                N_Push_Constraint_Error_Label            |
567                N_Push_Program_Error_Label               |
568                N_Push_Storage_Error_Label               |
569                N_Qualified_Expression                   |
570                N_Range                                  |
571                N_Range_Constraint                       |
572                N_Real_Literal                           |
573                N_Real_Range_Specification               |
574                N_Record_Definition                      |
575                N_Reference                              |
576                N_Selected_Component                     |
577                N_Signed_Integer_Type_Definition         |
578                N_Single_Protected_Declaration           |
579                N_Slice                                  |
580                N_String_Literal                         |
581                N_Subprogram_Info                        |
582                N_Subtype_Indication                     |
583                N_Subunit                                |
584                N_Task_Definition                        |
585                N_Terminate_Alternative                  |
586                N_Triggering_Alternative                 |
587                N_Type_Conversion                        |
588                N_Unchecked_Expression                   |
589                N_Unchecked_Type_Conversion              |
590                N_Unconstrained_Array_Definition         |
591                N_Unused_At_End                          |
592                N_Unused_At_Start                        |
593                N_Use_Package_Clause                     |
594                N_Use_Type_Clause                        |
595                N_Variant                                |
596                N_Variant_Part                           |
597                N_Validate_Unchecked_Conversion          |
598                N_With_Clause
599             =>
600                null;
601
602          end case;
603
604          --  If we fall through above tests, keep climbing tree
605
606          if Nkind (Parent (P)) = N_Subunit then
607
608             --  This is the proper body corresponding to a stub. Insertion done
609             --  at the point of the stub, which is in the declarative part of
610             --  the parent unit.
611
612             P := Corresponding_Stub (Parent (P));
613
614          else
615             P := Parent (P);
616          end if;
617       end loop;
618
619       --  SCIL node not found
620
621       return Empty;
622    end Find_SCIL_Node;
623
624    -------------------------
625    -- First_Non_SCIL_Node --
626    -------------------------
627
628    function First_Non_SCIL_Node (L : List_Id) return Node_Id is
629       N : Node_Id;
630
631    begin
632       N := First (L);
633       while Nkind (N) in N_SCIL_Node loop
634          Next (N);
635       end loop;
636
637       return N;
638    end First_Non_SCIL_Node;
639
640    ------------------------
641    -- Next_Non_SCIL_Node --
642    ------------------------
643
644    function Next_Non_SCIL_Node (N : Node_Id) return Node_Id is
645       Aux_N : Node_Id;
646
647    begin
648       Aux_N := Next (N);
649       while Nkind (Aux_N) in N_SCIL_Node loop
650          Next (Aux_N);
651       end loop;
652
653       return Aux_N;
654    end Next_Non_SCIL_Node;
655
656 end Sem_SCIL;