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