1------------------------------------------------------------------------------
2--                                                                          --
3--                  COMMON ASIS TOOLS COMPONENTS LIBRARY                    --
4--                                                                          --
5--                 A S I S _ U L . G L O B A L _ S T A T E
6--                                                                          --
7--                                 S p e c                                  --
8--                                                                          --
9--                     Copyright (C) 2007-2013, AdaCore                     --
10--                                                                          --
11-- Asis Utility Library (ASIS UL) is free software; you can redistribute it --
12-- and/or  modify  it  under  terms  of  the  GNU General Public License as --
13-- published by the Free Software Foundation; either version 2, or (at your --
14-- option)  any later version.  ASIS UL  is distributed in the hope that it --
15-- will  be  useful,  but  WITHOUT  ANY  WARRANTY; without even the implied --
16-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
17-- GNU  General Public License for more details. You should have received a --
18-- copy of the  GNU General Public License  distributed with GNAT; see file --
19-- COPYING. If not,  write  to the  Free Software Foundation,  51 Franklin  --
20-- Street, Fifth Floor, Boston, MA 02110-1301, USA.                         --
21--                                                                          --
22-- ASIS UL is maintained by AdaCore (http://www.adacore.com).               --
23--                                                                          --
24------------------------------------------------------------------------------
25
26--  This package defines the top of the subhierarchy describing the global
27--  state of the set of sources being analyzed.
28
29pragma Ada_05;
30
31with Ada.Containers.Ordered_Sets;
32
33with Asis;                    use Asis;
34with Asis.Extensions.Strings; use Asis.Extensions.Strings;
35
36with Types;                   use Types;
37
38with ASIS_UL.Source_Table;    use ASIS_UL.Source_Table;
39
40package ASIS_UL.Global_State is
41
42   --  The global state is represented as a single set of nodes representing
43   --  entities  of different kinds. The global structure represents various
44   --  relations between the corresponding entities. Depending on the following
45   --  flags, it may contain this or that information.
46
47   ---------------------
48   --  Global options --
49   ---------------------
50
51   function Compute_Global_Objects_Accessed return Boolean;
52
53   procedure Do_Compute_Global_Objects_Accessed;
54   --  Set an internal flag to compute global objects accessed directly or
55   --  indirectly by subprograms
56
57   ----------------------------------
58   --  Global structure node kinds --
59   ----------------------------------
60
61   type GS_Node_Kinds is
62     (Not_A_Node,
63      --  A null (absent or non-inialized) node
64
65      --  Callable nodes
66      Environment_Task,
67      A_Package,
68      A_Procedure,
69      A_Null_Procedure,
70      A_Type_Discr_Init_Procedure,
71      A_Type_Init_Procedure,
72      A_Function,
73      A_Task,
74      A_Task_Entry,
75      A_Protected_Procedure,
76      A_Protected_Function,
77      A_Protected_Entry,
78
79      --  Data nodes
80      A_Data_Object
81
82      --  To be continued???
83      );
84
85   --  Nodes for which there all variable declarations should be considered
86   --  as global
87   subtype Global_Nodes is GS_Node_Kinds range
88     Environment_Task .. A_Package;
89   subtype Callable_Nodes is GS_Node_Kinds range
90     Environment_Task .. A_Protected_Entry;
91
92   subtype Subprogram_Nodes is Callable_Nodes range A_Procedure .. A_Function;
93   subtype Protected_Subprogram_Nodes is Callable_Nodes range
94     A_Protected_Procedure .. A_Protected_Function;
95
96   ------------------------------------------
97   -- Callable entities and the call graph --
98   ------------------------------------------
99
100   --  The call graph consists of callable entities and caller-to-callee
101   --  relations among them. The call graph gives a static and "flat" picture,
102   --  it is not suitable for analysing properties specific for asynchronous
103   --  processes. The call graph contains the following nodes:
104   --
105   --    Environment_Task
106   --       This node represents an environment task, the call graph contains
107   --       exactly one node of this kind. Environment task calls all the
108   --       library level tasks, and it also calls the main subprogram if the
109   --       main subprogram is specified. It also calls all the subprograms
110   --       that that are called when from the elaboration of library packages.
111   --       Nobody can call this node. This node represents the most global
112   --       (library-level) scope.
113   --
114   --    A_Procedure
115   --    A_Function
116   --       Represent subprograms and subprogram instantiations. A subprogram
117   --       is an entity declared by a subprogram declaration, subprogram body
118   --       declaration or subprogram body stub in case there is no separate
119   --       spec provided for the given subprogram. Subprogram renamings that
120   --       are renamings as declarations are not counted for the call graph.
121   --       In case of renaming as a body, if renaming can be resolved
122   --       statically, this situation is considered as if the given subprogram
123   --       calls the entity being renamed.
124   --
125   --    A_Null_Procedure
126   --       Represents a null procedure (Ada 2005). The reason to define a
127   --       separate kind for null procedures is that for these procedures it
128   --       is known in advance that they do not have any code and they cannot
129   --       call, access or update anything.
130   --
131   --    A_Task
132   --       Represents a task that is viewed not as an asynchronous process,
133   --       but as a procedure. That is, creation of a task is considered as
134   --       a call to a procedure, where the task body is viewed as the body
135   --       of the called procedure (in other words, we do not make the
136   --       difference between "to call a process" and "to start a process").
137   --       ??? Needs better documentation
138   --
139   --    A_Task_Entry
140   --       The call graph considers a task entry call as a procedure call. The
141   --       body of this "procedure" is a code of all the accept statements
142   --       corresponding to this entry. Enclosing scope for a task entry is
143   --       the task entity the entry belongs to.
144   --
145   --    A_Protected_Procedure
146   --    A_Protected_Function
147   --       We make the difference between "normal" subprograms and protected
148   --       subprograms
149   --
150   --    A_Protected_Entry
151   --       Similar to A_Task_Entry, but for protected entry we have the
152   --       entry body instead of a set of accept statements code, and there
153   --       is no "parent" reference here (the call graph does not contain
154   --       any information about protected types and objects as whole
155   --       entities)
156
157   -------------------
158   -- Data entities --
159   -------------------
160
161   --  To be documented...
162
163   type GS_Node_Id is new Integer range 0 .. Integer'Last;
164   --  Index of the nodes representing the global state
165
166   No_GS_Node    : constant GS_Node_Id := GS_Node_Id'First;
167   First_GS_Node : constant GS_Node_Id := No_GS_Node + 1;
168
169   Environment_Task_Node : GS_Node_Id;
170   --  Node representing the environment task
171
172   subtype Existing_GS_Node_Id is GS_Node_Id
173     range First_GS_Node .. GS_Node_Id'Last;
174
175   type Reference_Kinds is
176   --  Classifies the references from callable entities to data entities
177     (Not_A_Reference,
178      --  Either not applicable or non-defined
179      Read,
180      --  Read reference
181      Write,
182      --  Write reference:
183      --  * variable in an assignment statement
184      --  * actual for a OUT parameter
185      Read_Write);
186      --  Reference that can be both read and write:
187      --  * actual for IN OUT parameter
188      --  * prefix of 'Access and 'Unchecked_Access attribute, we are
189      --    over-pessimistic in this case;
190
191   ------------
192   -- Scopes --
193   ------------
194
195   --  Scopes are statically enclosed bodies of callable entities,
196   --  Environment_Task_Node represents the outermost (library-level) scope.
197   --  Scopes are stored in the stack according to their nesting
198
199   subtype Scope_Id is GS_Node_Id;
200   No_Scope  : constant Scope_Id := Scope_Id'First;
201
202   procedure Set_Current_Scope (Scope : GS_Node_Id; Scope_Tree_Node : Node_Id);
203   --  Puts the argument on the top of the scope set. We need the corresponding
204   --  tree node to check if an entity is global for the current scope.
205
206   procedure Remove_Current_Scope;
207   --  Pops the top scope from the stack. Raises Scope_Stack_Error if the scope
208   --  stack is empty
209
210   function Current_Scope return Scope_Id;
211   --  Returns the top entity from the scope stack. Returns No_Scope_Ind if the
212   --  stack is empty
213
214   function Current_Scope_Tree_Node return Node_Id;
215   --  Returns the tree node for the current scope. This node always belongs
216   --  to the currently accessed tree.
217
218   Scope_Stack_Error : exception;
219
220   -----------
221   -- Links --
222   -----------
223
224   --  The global data structure keeps links between nodes. All links are
225   --  ordered, that is, a link goes from node A to node B, each link is stored
226   --  for the node it goes from (that is, for A). There are two kinds of
227   --  links - links that keep SLOCs of the place in the code that is a reason
228   --  to store this link as a part of the global structure (such as a location
229   --  of a subprogram call or a location of the reference to a data object),
230   --  and links that keep only the nodes to which the link goes to, such
231   --  links are used to represent such information as a list of all the
232   --  entities called by a given subprogram, directly or indirectly, or a list
233   --  of all the (global) data objects referenced by a given subprograms,
234   --  directly or indirectly. If a link represent some indirect relation,
235   --  there is no sense to keep a SLOC information for it. Keeping SLOCs for
236   --  direct links allows to generate useful (back)trace information.
237
238   --  The data structure keeps only one link for each event such as a call
239   --  or a reference (that is, if a procedure A calls the procedure B many
240   --  times (there are many procedure call statements targeted to B in the
241   --  code of A), the node that represents A keeps only one link from A to B).
242   --  Usually the SLOC stored as a part of this link corresponds to the
243   --  (textually) first occurence of this event in the code.
244
245   type SLOC_Link is record
246      Node : GS_Node_Id;
247      SLOC : String_Loc;
248   end record;
249
250   subtype Link is GS_Node_Id;
251
252   ----------------------------
253   -- Storage for node links --
254   ----------------------------
255
256   function "<" (Left, Right : SLOC_Link) return Boolean;
257   function "=" (Left, Right : SLOC_Link) return Boolean;
258   --  These functions compare only node Ids and ignore SLOCs.
259
260   package SLOC_Node_Lists is new Ada.Containers.Ordered_Sets
261     (Element_Type => SLOC_Link);
262   --  Represents ordered sets of node links. Each link from this set contains
263   --  a SLOC of the place from which this link originates
264
265   package Node_Lists is new Ada.Containers.Ordered_Sets
266     (Element_Type => Link);
267   --  Represents ordered sets of node links (with no SLOC information)
268
269   --  We need links to nodes with SLOCs in case if we have to generated
270   --  useful call (back)traces (that say not only who is called, but also
271   --  where it is called). But it is too expansive to use the link lists with
272   --  SLOCs for big lists, such as list of all the calls (moreover, for an
273   --  indirect call SLOC does not make very much sense)
274
275   type SLOC_Node_List_Access is access SLOC_Node_Lists.Set;
276   type Node_List_Access is access Node_Lists.Set;
277   --  We need these access types to get node lists that represents call chains
278   --  or other similar information for nodes in global structure
279
280   --------------------------------------------------------
281   -- General global structure entities/nodes properties --
282   --------------------------------------------------------
283
284   function Present (N : GS_Node_Id) return Boolean;
285   function No      (N : GS_Node_Id) return Boolean;
286   --  Check if the argument represents a nonexistent node
287
288   function Last_Node return GS_Node_Id;
289   --  Returtns the last node stored in the global state.
290
291   function GS_Node_Kind (N : GS_Node_Id) return GS_Node_Kinds;
292   --  Returns the kind of the argument node. Returns Not_A_Node if No (N).
293
294   function Is_Callable_Node (N : GS_Node_Id) return Boolean;
295   --  Checks if N represents a callable entity
296
297   function Is_Subprogram_Node (N : GS_Node_Id) return Boolean;
298   --  Checks if N represents a subprogram or a protected subprogram.
299
300   function Is_Dispatching_Operation_Node (N : GS_Node_Id) return Boolean;
301   --  Checks if N represents a dispatching operation. Accepts nodes that do
302   --  not represent subprograms and returns False for them
303
304   function Is_Abstract_Subprogram_Node (N : GS_Node_Id) return Boolean;
305   --  Checks if N represents an abstract subprogram. Accepts nodes that do
306   --  not represent subprograms and returns False for them
307
308   function Is_Implicit_Subprogram_Node (N : GS_Node_Id) return Boolean;
309   --  Checks if N represents an impilictly defined inherited subprogram.
310   --  Accepts nodes that do not represent subprograms and returns False for
311   --  them
312
313   function GS_Node_SLOC (N : GS_Node_Id) return String_Loc;
314   --  Returns the Source LOCation of the Ada construct the Node originated
315   --  from. Returns Nil_String_Loc for Environment_Task node and in case when
316   --  No (N)
317
318   function GS_Node_Name (N : GS_Node_Id) return String;
319   --  Retirns the name of the entity denoted by N. In case of expanded
320   --  defining name the full expandsed name is returned
321   --  ??? Should this function return Wide_String???
322
323   function GS_Enclosed_CU_Name (N : GS_Node_Id) return String;
324   --  Returns the name of the Compilation Unit that encloses the entity
325   --  denoted by N;
326   --  ??? Should this function return Wide_String???
327
328   function GS_Node_Enclosing_Scope (N : GS_Node_Id) return Scope_Id;
329   --  Returns the node that is a scope for the argument node. Returns
330   --  No_GS_Node for Environment_Task node. Returns No_Scope if No (N).
331
332   function GS_Node_Scope_Level (N : GS_Node_Id) return Natural;
333   --  Returns the scope level. Node scope level is the nesting level of the
334   --  scope the entity represented by the node belongs to (if the node itself
335   --  is a scope, it is considered as belonging to itself). Environment_Task
336   --  node has a scope level 1. Raises Constraint_Error is No (N)
337   --  ??? See the documentation of Scope_Level field of the GS_Node_Record
338   --  type. Needs to be cleaned up.
339
340   function Is_RTL_Node (N : GS_Node_Id) return Boolean;
341   --  Checks if the argument node represents an entity from some RTL unit.
342   --  Raises Constraint_Error is No (N).
343
344   function Is_Of_No_Interest (N : GS_Node_Id) return Boolean;
345   --  Returns True if we are 100% sure that the given node cannot be of any
346   --  interest for any analysis that can be performed on the global program
347   --  structure. Raises Constraint_Error is No (N).
348
349   function Enclosing_Source (N : GS_Node_Id) return SF_Id;
350   --  Returns the ID of the source file the node has been extracted from.
351   --  Returns No_SF_Id for Environment_Task. Raises Constraint_Error if
352   --  No (N).
353
354   function  Get_Application_Flag_1 (N : GS_Node_Id) return Boolean;
355   procedure Set_Application_Flag_1 (N : GS_Node_Id; Val : Boolean);
356
357   function Direct_Calls (N : GS_Node_Id) return SLOC_Node_List_Access;
358   function All_Calls (N : GS_Node_Id) return Node_List_Access;
359   --  Assuming that Is_Callable_Node (N), return (pointer to) the list of
360   --  direct or all calls
361
362   function Direct_Reads (N : GS_Node_Id) return SLOC_Node_List_Access;
363   function Direct_Writes (N : GS_Node_Id) return SLOC_Node_List_Access;
364   function Indirect_Reads (N : GS_Node_Id) return Node_List_Access;
365   function Indirect_Writes (N : GS_Node_Id) return Node_List_Access;
366   --  Assuming that Is_Callable_Node (N), return (pointer to) the list of
367   --  direct or indirect reads or writes
368
369   ---------------------------------------
370   -- General global structure routines --
371   ---------------------------------------
372
373   procedure Initialize;
374   --  Initializes the data structures needed to represent the global state.
375
376   function Corresponding_Node
377     (El              : Element;
378      Enclosing_Scope : Scope_Id      := No_Scope;
379      Expected_Kind   : GS_Node_Kinds := Not_A_Node;
380      Unconditionally : Boolean       := False)
381      return            GS_Node_Id;
382   --  Returns the Id of the global structure node corresponding to El. If this
383   --  El has not been added to the global structure yet, creates the
384   --  corresponding node and returns it as the result. If set to non-empty
385   --  value, Enclosing_Scope parameter is used to specify the enclosing scope
386   --  for the node to be created.
387   --
388   --  If Expected_Kind is set to some value different from Not_A_Node, then
389   --  this procedure looks for/creates the node of the specified kind.
390   --
391   --  Call to this function may result in creating more than one node in the
392   --  global structure. For example, in the call graph, when creating a node
393   --  for a callable entity, this function needs to set its scope link, and if
394   --  the scope node does not exist, it is created, and the scope's scope
395   --  node, and so on. For a type initialization routine it computes all the
396   --  calls issued by this routine and creates the corresponding nodes and
397   --  links in the call graph.
398   --
399   --  Creation of the new node may result in adding a new source file in the
400   --  source files table (as a needed source). It may be the case when a call
401   --  to this function adds more than one needed source (in case we create
402   --  a node for some callable entity defined in a proper body of a subunit,
403   --  then creation of the corresponding node may result in adding as a needed
404   --  source the source for the body where the stub is located and the source
405   --  of the corresponding spec).
406
407   --------------------
408   -- Debug routines --
409   --------------------
410
411   procedure Print_Global_Structure;
412   --  Generates into Stderr the debug output for global data structure
413   --  if the corresponding debug flag is ON (or if ASIS_UL.Options.Debug_Mode
414   --  is ON, but we have to get rid of this flag), otherwise does nothing.
415
416   procedure Print_Node (N : GS_Node_Id);
417   --  Outputs into Stderr the debug information about the argument node N.
418   --  format of the output
419
420   procedure Print_List      (Node_List : Node_Lists.Set);
421   procedure Print_SLOC_List (Node_List : SLOC_Node_Lists.Set);
422   --  Debug routines, print into Stderr the debug image of the argument link
423   --  list of nodes (without or with SLOC info).
424
425private
426
427   --  The entities below are needed only for the implementation of the
428   --  global data structure.
429
430   procedure Add_SLOC_Node_List_To_Node_List
431     (Target : in out Node_Lists.Set;
432      Source :        SLOC_Node_Lists.Set);
433   --  This procedure is similar to the Union set container operation, the
434   --  only difference is that Source is a link list with SLOCs, but Target
435   --  does not have SLOCs (SLOCs parts from the elements of SOURCE are
436   --  abandoned)
437
438   -----------------------------------------------------
439   --  General structure of the global structure node --
440   -----------------------------------------------------
441
442   type GS_Node_Record is record
443
444      -------------------
445      -- Common fields --
446      -------------------
447
448      --  Fields that exist for all entities. Should we use a discriminanted
449      --  record here???
450
451      Node_Kind : GS_Node_Kinds;
452
453      SLOC : String_Loc;
454      --  The full string location of the node (in case of generic
455      --  instantiations includes the full istantiation chain)
456
457      Name : String_Loc;
458      --  Name of the entity represented by the node
459
460      Source_File : SF_Id;
461      --  Source file the given node belongs to.
462
463      Enclosing_Scope : Scope_Id;
464
465      Scope_Level : Natural;
466      --  For a scope node, represents the nesting level of the scope.
467      --  Is needed for analyzing if a data object is global for a scope, The
468      --  scope level of an environment task is 1. If the node is not a scope,
469      --  or if it corresponds to a subprogram for that the body has not been
470      --  analyzed yet, the scope level is 0.
471
472      Hash_Link : GS_Node_Id;
473      --  Link to the next entry in the node table for the same hash code.
474
475      Is_RTL_Node : Boolean;
476      --  Indicates if the given node represents an entity defined in RTL.
477
478      Is_Of_No_Interest : Boolean;
479      --  Indicates if the node is of no interest for further analysis because
480      --  of any reason. For example, a node represents a function that is an
481      --  enumeration literal renaming - such function cannot call anything and
482      --  it cannot refer to any data object
483
484      --------------------------------------------------------------
485      -- The meaning of the following fields depends on node kind --
486      --------------------------------------------------------------
487
488      Bool_Flag_1 : Boolean;
489      --  Callable_Node -> Is_Body_Analyzed;
490      --  Data_Node     -> ???
491
492      Bool_Flag_2 : Boolean;
493      --  Callable_Node -> Is_Renaming;
494      --  Data_Node     -> ???
495
496      Bool_Flag_3 : Boolean;
497      --  Callable_Node ->
498      --     A_Task              A_Task -> Is_Task_Type
499      --     other callable nodes -> ???
500      --  Data_Node     -> ???
501
502      Bool_Flag_4 : Boolean;
503      --  Callable_Node -> Is_Dispatching_Operation_Node;
504      --  Data_Node     -> ???
505
506      Bool_Flag_5 : Boolean;
507      --  Callable_Node -> Is_Abstract_Subprogram_Node;
508      --  Data_Node     -> ???
509
510      Bool_Flag_6 : Boolean;
511      --  Callable_Node -> Is_Implicit_Subprogram_Node;
512      --  Data_Node     -> ???
513
514--      Bool_Flag_7 : Boolean;
515      --  Callable_Node -> Is_Called_Dispatching_Root;
516      --  Data_Node     -> ???
517
518      Application_Flag_1 : Boolean;
519      --  The usage of this flag is up to an application implemented on top of
520      --  this call graph structure.
521
522      SLOC_Node_List_1 : SLOC_Node_Lists.Set;
523      --  Callable_Node -> Direct_Calls;
524      --  Data_Node     -> ???
525
526      SLOC_Node_List_2 : SLOC_Node_Lists.Set;
527      --  For a callable node - references to global objects directly read by
528      --  the callable entity.
529      --  For a data node - list of all the callable entities that directly
530      --  read the data entity.
531
532      SLOC_Node_List_3 : SLOC_Node_Lists.Set;
533      --  For a callable node - references to global objects directly written
534      --  by the callable entity.
535      --  For a data node - list of all the callable entities that directly
536      --  write the data entity.
537
538      Node_List_1 : Node_Lists.Set;
539      --  Callable_Node -> All_Calls;
540      --  Data_Node     -> ???
541
542      Node_List_2 : Node_Lists.Set;
543      --  Callable_Node ->
544      --    Direct dispatching calls
545      --  Data_Node     -> ???
546
547      Node_List_3 : Node_Lists.Set;
548      --  Callable_Node ->
549      --    Is_Dispatching_Operation_Node ->
550      --       Directly implementing subprograms
551      --  Data_Node     -> ???
552
553      Node_List_4 : Node_Lists.Set;
554      --  Callable_Node ->
555      --    Is_Dispatching_Operation_Node ->
556      --       All implementing subprograms  ???
557      --  Data_Node     -> ???
558
559      Node_List_5 : Node_Lists.Set;
560      --  For a callable node - references to global objects indirectly read by
561      --  the callable entity.
562      --  For a data node - list of all the callable entities that indirectly
563      --  read the data entity.
564
565      Node_List_6 : Node_Lists.Set;
566      --  For a callable node - references to global objects indirectly written
567      --  by the callable entity.
568      --  For a data node - list of all the callable entities that indirectly
569      --  write the data entity.
570
571   end record;
572
573   --------------------------------
574   -- Access and update routines --
575   --------------------------------
576
577   type SLOC_Link_List_Types is
578     (Calls,
579      Direct_Read_References,
580      Direct_Write_References,
581      Indirect_Read_References,
582      Indirect_Write_References
583      --  To be continued...
584     );
585   --  Used to identify a list to operate with
586
587   procedure Add_Link_To_SLOC_List
588     (To_Node     : GS_Node_Id;
589      Link_To_Add : SLOC_Link;
590      To_List     : SLOC_Link_List_Types := Calls);
591   --  Adds new link to the list pointed by To_List parameter of To_Node. If a
592   --  link with the node from the argument link is already in the list,
593   --  does nothing.
594
595   type GS_Node_Record_Access is access GS_Node_Record;
596
597   function Table (N : GS_Node_Id) return GS_Node_Record_Access;
598   --  Mimics the notation Instantce_Name.Table (N) in the instantiation of the
599   --  GNAT Table package. Returns the (pointer to the )Node with the index N
600   --  from GS_Nodes_Table (see the body of the package). Raises
601   --  Constraint_Error if a node with this index does not exsist.
602
603   procedure Set_Is_Of_No_Interest (N : GS_Node_Id; Val : Boolean := True);
604   --  Set the flag indicating if the callable entity is of no interest.
605
606   --  Low-level procedures for setting fields tha are specific for
607   --  node kind:
608   procedure Set_Bool_Flag_1 (N : GS_Node_Id; Val : Boolean);
609   procedure Set_Bool_Flag_2 (N : GS_Node_Id; Val : Boolean);
610   procedure Set_Bool_Flag_3 (N : GS_Node_Id; Val : Boolean);
611   procedure Set_Bool_Flag_4 (N : GS_Node_Id; Val : Boolean);
612   procedure Set_Bool_Flag_5 (N : GS_Node_Id; Val : Boolean);
613   procedure Set_Bool_Flag_6 (N : GS_Node_Id; Val : Boolean);
614
615end ASIS_UL.Global_State;
616