1------------------------------------------------------------------------------ 2-- -- 3-- GNAT COMPILER COMPONENTS -- 4-- -- 5-- B I N D O . B U I L D E R S -- 6-- -- 7-- B o d y -- 8-- -- 9-- Copyright (C) 2019, 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 26with Binderr; use Binderr; 27with Butil; use Butil; 28with Debug; use Debug; 29with Opt; use Opt; 30with Output; use Output; 31with Types; use Types; 32 33with Bindo.Units; use Bindo.Units; 34 35with Bindo.Validators; 36use Bindo.Validators; 37use Bindo.Validators.Invocation_Graph_Validators; 38use Bindo.Validators.Library_Graph_Validators; 39 40with Bindo.Writers; 41use Bindo.Writers; 42use Bindo.Writers.Phase_Writers; 43 44with GNAT; use GNAT; 45with GNAT.Dynamic_HTables; use GNAT.Dynamic_HTables; 46 47package body Bindo.Builders is 48 49 ------------------------------- 50 -- Invocation_Graph_Builders -- 51 ------------------------------- 52 53 package body Invocation_Graph_Builders is 54 55 ----------------- 56 -- Global data -- 57 ----------------- 58 59 Inv_Graph : Invocation_Graph := Invocation_Graphs.Nil; 60 Lib_Graph : Library_Graph := Library_Graphs.Nil; 61 62 ----------------------- 63 -- Local subprograms -- 64 ----------------------- 65 66 procedure Create_Edge (IR_Id : Invocation_Relation_Id); 67 pragma Inline (Create_Edge); 68 -- Create a new edge for invocation relation IR_Id in invocation graph 69 -- Inv_Graph. 70 71 procedure Create_Edges (U_Id : Unit_Id); 72 pragma Inline (Create_Edges); 73 -- Create new edges for all invocation relations of unit U_Id 74 75 procedure Create_Vertex 76 (IC_Id : Invocation_Construct_Id; 77 Vertex : Library_Graph_Vertex_Id); 78 pragma Inline (Create_Vertex); 79 -- Create a new vertex for invocation construct IC_Id in invocation 80 -- graph Inv_Graph. The vertex is linked to vertex Vertex of library 81 -- graph Lib_Graph. 82 83 procedure Create_Vertices (U_Id : Unit_Id); 84 pragma Inline (Create_Vertices); 85 -- Create new vertices for all invocation constructs of unit U_Id in 86 -- invocation graph Inv_Graph. 87 88 function Declaration_Placement_Vertex 89 (Vertex : Library_Graph_Vertex_Id; 90 Placement : Declaration_Placement_Kind) 91 return Library_Graph_Vertex_Id; 92 pragma Inline (Declaration_Placement_Vertex); 93 -- Obtain the spec or body of vertex Vertex depending on the requested 94 -- placement in Placement. 95 96 ---------------------------- 97 -- Build_Invocation_Graph -- 98 ---------------------------- 99 100 function Build_Invocation_Graph 101 (Lib_G : Library_Graph) return Invocation_Graph 102 is 103 begin 104 pragma Assert (Present (Lib_G)); 105 106 Start_Phase (Invocation_Graph_Construction); 107 108 -- Prepare the global data 109 110 Inv_Graph := 111 Create 112 (Initial_Vertices => Number_Of_Elaborable_Units, 113 Initial_Edges => Number_Of_Elaborable_Units); 114 Lib_Graph := Lib_G; 115 116 For_Each_Elaborable_Unit (Create_Vertices'Access); 117 For_Each_Elaborable_Unit (Create_Edges'Access); 118 119 Validate_Invocation_Graph (Inv_Graph); 120 End_Phase (Invocation_Graph_Construction); 121 122 return Inv_Graph; 123 end Build_Invocation_Graph; 124 125 ----------------- 126 -- Create_Edge -- 127 ----------------- 128 129 procedure Create_Edge (IR_Id : Invocation_Relation_Id) is 130 pragma Assert (Present (Inv_Graph)); 131 pragma Assert (Present (Lib_Graph)); 132 pragma Assert (Present (IR_Id)); 133 134 Invoker_Sig : constant Invocation_Signature_Id := Invoker (IR_Id); 135 Target_Sig : constant Invocation_Signature_Id := Target (IR_Id); 136 137 pragma Assert (Present (Invoker_Sig)); 138 pragma Assert (Present (Target_Sig)); 139 140 begin 141 -- Nothing to do when the target denotes an invocation construct that 142 -- resides in a unit which will never be elaborated. 143 144 if not Needs_Elaboration (Target_Sig) then 145 return; 146 end if; 147 148 Add_Edge 149 (G => Inv_Graph, 150 Source => Corresponding_Vertex (Inv_Graph, Invoker_Sig), 151 Target => Corresponding_Vertex (Inv_Graph, Target_Sig), 152 IR_Id => IR_Id); 153 end Create_Edge; 154 155 ------------------ 156 -- Create_Edges -- 157 ------------------ 158 159 procedure Create_Edges (U_Id : Unit_Id) is 160 pragma Assert (Present (Inv_Graph)); 161 pragma Assert (Present (Lib_Graph)); 162 pragma Assert (Present (U_Id)); 163 164 U_Rec : Unit_Record renames ALI.Units.Table (U_Id); 165 166 begin 167 for IR_Id in U_Rec.First_Invocation_Relation .. 168 U_Rec.Last_Invocation_Relation 169 loop 170 Create_Edge (IR_Id); 171 end loop; 172 end Create_Edges; 173 174 ------------------- 175 -- Create_Vertex -- 176 ------------------- 177 178 procedure Create_Vertex 179 (IC_Id : Invocation_Construct_Id; 180 Vertex : Library_Graph_Vertex_Id) 181 is 182 begin 183 pragma Assert (Present (Inv_Graph)); 184 pragma Assert (Present (Lib_Graph)); 185 pragma Assert (Present (IC_Id)); 186 pragma Assert (Present (Vertex)); 187 188 Add_Vertex 189 (G => Inv_Graph, 190 IC_Id => IC_Id, 191 Body_Vertex => 192 Declaration_Placement_Vertex 193 (Vertex => Vertex, 194 Placement => Body_Placement (IC_Id)), 195 Spec_Vertex => 196 Declaration_Placement_Vertex 197 (Vertex => Vertex, 198 Placement => Spec_Placement (IC_Id))); 199 end Create_Vertex; 200 201 --------------------- 202 -- Create_Vertices -- 203 --------------------- 204 205 procedure Create_Vertices (U_Id : Unit_Id) is 206 pragma Assert (Present (Inv_Graph)); 207 pragma Assert (Present (Lib_Graph)); 208 pragma Assert (Present (U_Id)); 209 210 U_Rec : Unit_Record renames ALI.Units.Table (U_Id); 211 Vertex : constant Library_Graph_Vertex_Id := 212 Corresponding_Vertex (Lib_Graph, U_Id); 213 214 begin 215 for IC_Id in U_Rec.First_Invocation_Construct .. 216 U_Rec.Last_Invocation_Construct 217 loop 218 Create_Vertex (IC_Id, Vertex); 219 end loop; 220 end Create_Vertices; 221 222 ---------------------------------- 223 -- Declaration_Placement_Vertex -- 224 ---------------------------------- 225 226 function Declaration_Placement_Vertex 227 (Vertex : Library_Graph_Vertex_Id; 228 Placement : Declaration_Placement_Kind) 229 return Library_Graph_Vertex_Id 230 is 231 begin 232 pragma Assert (Present (Lib_Graph)); 233 pragma Assert (Present (Vertex)); 234 235 if Placement = In_Body then 236 return Proper_Body (Lib_Graph, Vertex); 237 else 238 pragma Assert (Placement = In_Spec); 239 return Proper_Spec (Lib_Graph, Vertex); 240 end if; 241 end Declaration_Placement_Vertex; 242 end Invocation_Graph_Builders; 243 244 ---------------------------- 245 -- Library_Graph_Builders -- 246 ---------------------------- 247 248 package body Library_Graph_Builders is 249 250 --------------------- 251 -- Data structures -- 252 --------------------- 253 254 procedure Destroy_Line_Number (Line : in out Logical_Line_Number); 255 pragma Inline (Destroy_Line_Number); 256 -- Destroy line number Line 257 258 function Hash_Unit (U_Id : Unit_Id) return Bucket_Range_Type; 259 pragma Inline (Hash_Unit); 260 -- Obtain the hash value of key U_Id 261 262 package Unit_Line_Tables is new Dynamic_Hash_Tables 263 (Key_Type => Unit_Id, 264 Value_Type => Logical_Line_Number, 265 No_Value => No_Line_Number, 266 Expansion_Threshold => 1.5, 267 Expansion_Factor => 2, 268 Compression_Threshold => 0.3, 269 Compression_Factor => 2, 270 "=" => "=", 271 Destroy_Value => Destroy_Line_Number, 272 Hash => Hash_Unit); 273 274 ----------------- 275 -- Global data -- 276 ----------------- 277 278 Lib_Graph : Library_Graph := Library_Graphs.Nil; 279 280 Unit_To_Line : Unit_Line_Tables.Dynamic_Hash_Table := 281 Unit_Line_Tables.Nil; 282 -- The map of unit name -> line number, used to detect duplicate unit 283 -- names in the forced-elaboration-order file and report errors. 284 285 ----------------------- 286 -- Local subprograms -- 287 ----------------------- 288 289 procedure Add_Unit 290 (U_Id : Unit_Id; 291 Line : Logical_Line_Number); 292 pragma Inline (Add_Unit); 293 -- Create a relationship between unit U_Id and its declaration line in 294 -- map Unit_To_Line. 295 296 procedure Create_Forced_Edge 297 (Pred : Unit_Id; 298 Succ : Unit_Id); 299 pragma Inline (Create_Forced_Edge); 300 -- Create a new forced edge between predecessor unit Pred and successor 301 -- unit Succ. 302 303 procedure Create_Forced_Edges; 304 pragma Inline (Create_Forced_Edges); 305 -- Inspect the contents of the forced-elaboration-order file, and create 306 -- specialized edges for each valid pair of units listed within. 307 308 procedure Create_Spec_And_Body_Edge (U_Id : Unit_Id); 309 pragma Inline (Create_Spec_And_Body_Edge); 310 -- Establish a link between the spec and body of unit U_Id. In certain 311 -- cases this may result in a new edge which is added to library graph 312 -- Lib_Graph. 313 314 procedure Create_Vertex (U_Id : Unit_Id); 315 pragma Inline (Create_Vertex); 316 -- Create a new vertex for unit U_Id in library graph Lib_Graph 317 318 procedure Create_With_Edge 319 (W_Id : With_Id; 320 Succ : Library_Graph_Vertex_Id); 321 pragma Inline (Create_With_Edge); 322 -- Create a new edge for with W_Id where the predecessor is the library 323 -- graph vertex of the withed unit, and the successor is Succ. The edge 324 -- is added to library graph Lib_Graph. 325 326 procedure Create_With_Edges (U_Id : Unit_Id); 327 pragma Inline (Create_With_Edges); 328 -- Establish links between unit U_Id and its predecessor units. The new 329 -- edges are added to library graph Lib_Graph. 330 331 procedure Create_With_Edges 332 (U_Id : Unit_Id; 333 Succ : Library_Graph_Vertex_Id); 334 pragma Inline (Create_With_Edges); 335 -- Create new edges for all withs of unit U_Id where the predecessor is 336 -- some withed unit, and the successor is Succ. The edges are added to 337 -- library graph Lib_Graph. 338 339 procedure Duplicate_Unit_Error 340 (U_Id : Unit_Id; 341 Nam : Unit_Name_Type; 342 Line : Logical_Line_Number); 343 pragma Inline (Duplicate_Unit_Error); 344 -- Emit an error concerning the duplication of unit U_Id with name Nam 345 -- that is redeclared in the forced-elaboration-order file at line Line. 346 347 procedure Internal_Unit_Info (Nam : Unit_Name_Type); 348 pragma Inline (Internal_Unit_Info); 349 -- Emit an information message concerning the omission of an internal 350 -- unit with name Nam from the creation of forced edges. 351 352 function Is_Duplicate_Unit (U_Id : Unit_Id) return Boolean; 353 pragma Inline (Is_Duplicate_Unit); 354 -- Determine whether unit U_Id is already recorded in map Unit_To_Line 355 356 function Is_Significant_With (W_Id : With_Id) return Boolean; 357 pragma Inline (Is_Significant_With); 358 -- Determine whether with W_Id plays a significant role in elaboration 359 360 procedure Missing_Unit_Info (Nam : Unit_Name_Type); 361 pragma Inline (Missing_Unit_Info); 362 -- Emit an information message concerning the omission of an undefined 363 -- unit found in the forced-elaboration-order file. 364 365 -------------- 366 -- Add_Unit -- 367 -------------- 368 369 procedure Add_Unit 370 (U_Id : Unit_Id; 371 Line : Logical_Line_Number) 372 is 373 begin 374 pragma Assert (Present (U_Id)); 375 376 Unit_Line_Tables.Put (Unit_To_Line, U_Id, Line); 377 end Add_Unit; 378 379 ------------------------- 380 -- Build_Library_Graph -- 381 ------------------------- 382 383 function Build_Library_Graph return Library_Graph is 384 begin 385 Start_Phase (Library_Graph_Construction); 386 387 -- Prepare the global data 388 389 Lib_Graph := 390 Create 391 (Initial_Vertices => Number_Of_Elaborable_Units, 392 Initial_Edges => Number_Of_Elaborable_Units); 393 394 For_Each_Elaborable_Unit (Create_Vertex'Access); 395 For_Each_Elaborable_Unit (Create_Spec_And_Body_Edge'Access); 396 For_Each_Elaborable_Unit (Create_With_Edges'Access); 397 Create_Forced_Edges; 398 399 Validate_Library_Graph (Lib_Graph); 400 End_Phase (Library_Graph_Construction); 401 402 return Lib_Graph; 403 end Build_Library_Graph; 404 405 ------------------------ 406 -- Create_Forced_Edge -- 407 ------------------------ 408 409 procedure Create_Forced_Edge 410 (Pred : Unit_Id; 411 Succ : Unit_Id) 412 is 413 pragma Assert (Present (Pred)); 414 pragma Assert (Present (Succ)); 415 416 Pred_Vertex : constant Library_Graph_Vertex_Id := 417 Corresponding_Vertex (Lib_Graph, Pred); 418 Succ_Vertex : constant Library_Graph_Vertex_Id := 419 Corresponding_Vertex (Lib_Graph, Succ); 420 421 begin 422 Write_Unit_Name (Name (Pred)); 423 Write_Str (" <-- "); 424 Write_Unit_Name (Name (Succ)); 425 Write_Eol; 426 427 Add_Edge 428 (G => Lib_Graph, 429 Pred => Pred_Vertex, 430 Succ => Succ_Vertex, 431 Kind => Forced_Edge, 432 Activates_Task => False); 433 end Create_Forced_Edge; 434 435 ------------------------- 436 -- Create_Forced_Edges -- 437 ------------------------- 438 439 procedure Create_Forced_Edges is 440 Current_Unit : Unit_Id; 441 Iter : Forced_Units_Iterator; 442 Previous_Unit : Unit_Id; 443 Unit_Line : Logical_Line_Number; 444 Unit_Name : Unit_Name_Type; 445 446 begin 447 Previous_Unit := No_Unit_Id; 448 Unit_To_Line := Unit_Line_Tables.Create (20); 449 450 -- Inspect the contents of the forced-elaboration-order file supplied 451 -- to the binder using switch -f, and diagnose each unit accordingly. 452 453 Iter := Iterate_Forced_Units; 454 while Has_Next (Iter) loop 455 Next (Iter, Unit_Name, Unit_Line); 456 457 Current_Unit := Corresponding_Unit (Unit_Name); 458 459 if not Present (Current_Unit) then 460 Missing_Unit_Info (Unit_Name); 461 462 elsif Is_Internal_Unit (Current_Unit) then 463 Internal_Unit_Info (Unit_Name); 464 465 elsif Is_Duplicate_Unit (Current_Unit) then 466 Duplicate_Unit_Error (Current_Unit, Unit_Name, Unit_Line); 467 468 -- Otherwise the unit is a valid candidate for a vertex. Create a 469 -- forced edge between each pair of units. 470 471 else 472 Add_Unit (Current_Unit, Unit_Line); 473 474 if Present (Previous_Unit) then 475 Create_Forced_Edge 476 (Pred => Previous_Unit, 477 Succ => Current_Unit); 478 end if; 479 480 Previous_Unit := Current_Unit; 481 end if; 482 end loop; 483 484 Unit_Line_Tables.Destroy (Unit_To_Line); 485 end Create_Forced_Edges; 486 487 ------------------------------- 488 -- Create_Spec_And_Body_Edge -- 489 ------------------------------- 490 491 procedure Create_Spec_And_Body_Edge (U_Id : Unit_Id) is 492 Extra_Vertex : Library_Graph_Vertex_Id; 493 Vertex : Library_Graph_Vertex_Id; 494 495 begin 496 pragma Assert (Present (Lib_Graph)); 497 pragma Assert (Present (U_Id)); 498 499 Vertex := Corresponding_Vertex (Lib_Graph, U_Id); 500 501 -- The unit denotes a body that completes a previous spec. Link the 502 -- spec and body. Add an edge between the predecessor spec and the 503 -- successor body. 504 505 if Is_Body_With_Spec (Lib_Graph, Vertex) then 506 Extra_Vertex := 507 Corresponding_Vertex (Lib_Graph, Corresponding_Spec (U_Id)); 508 Set_Corresponding_Item (Lib_Graph, Vertex, Extra_Vertex); 509 510 Add_Edge 511 (G => Lib_Graph, 512 Pred => Extra_Vertex, 513 Succ => Vertex, 514 Kind => Spec_Before_Body_Edge, 515 Activates_Task => False); 516 517 -- The unit denotes a spec with a completing body. Link the spec and 518 -- body. 519 520 elsif Is_Spec_With_Body (Lib_Graph, Vertex) then 521 Extra_Vertex := 522 Corresponding_Vertex (Lib_Graph, Corresponding_Body (U_Id)); 523 Set_Corresponding_Item (Lib_Graph, Vertex, Extra_Vertex); 524 end if; 525 end Create_Spec_And_Body_Edge; 526 527 ------------------- 528 -- Create_Vertex -- 529 ------------------- 530 531 procedure Create_Vertex (U_Id : Unit_Id) is 532 begin 533 pragma Assert (Present (Lib_Graph)); 534 pragma Assert (Present (U_Id)); 535 536 Add_Vertex 537 (G => Lib_Graph, 538 U_Id => U_Id); 539 end Create_Vertex; 540 541 ---------------------- 542 -- Create_With_Edge -- 543 ---------------------- 544 545 procedure Create_With_Edge 546 (W_Id : With_Id; 547 Succ : Library_Graph_Vertex_Id) 548 is 549 pragma Assert (Present (Lib_Graph)); 550 pragma Assert (Present (W_Id)); 551 pragma Assert (Present (Succ)); 552 553 Withed_Rec : With_Record renames Withs.Table (W_Id); 554 Withed_U_Id : constant Unit_Id := 555 Corresponding_Unit (Withed_Rec.Uname); 556 557 Kind : Library_Graph_Edge_Kind; 558 Withed_Vertex : Library_Graph_Vertex_Id; 559 560 begin 561 -- Nothing to do when the withed unit does not need to be elaborated. 562 -- This prevents spurious dependencies that can never be satisfied. 563 564 if not Needs_Elaboration (Withed_U_Id) then 565 return; 566 end if; 567 568 Withed_Vertex := Corresponding_Vertex (Lib_Graph, Withed_U_Id); 569 570 -- The with comes with pragma Elaborate. Treat the edge as a with 571 -- edge when switch -d_e (ignore the effects of pragma Elaborate) 572 -- is in effect. 573 574 if Withed_Rec.Elaborate 575 and then not Debug_Flag_Underscore_E 576 then 577 Kind := Elaborate_Edge; 578 579 -- The withed unit is a spec with a completing body. Add an edge 580 -- between the body of the withed predecessor and the withing 581 -- successor. 582 583 if Is_Spec_With_Body (Lib_Graph, Withed_Vertex) then 584 Add_Edge 585 (G => Lib_Graph, 586 Pred => 587 Corresponding_Vertex 588 (Lib_Graph, Corresponding_Body (Withed_U_Id)), 589 Succ => Succ, 590 Kind => Kind, 591 Activates_Task => False); 592 end if; 593 594 -- The with comes with pragma Elaborate_All. Treat the edge as a with 595 -- edge when switch -d_a (ignore the effects of pragma Elaborate_All) 596 -- is in effect. 597 598 elsif Withed_Rec.Elaborate_All 599 and then not Debug_Flag_Underscore_A 600 then 601 Kind := Elaborate_All_Edge; 602 603 -- Otherwise this is a regular with 604 605 else 606 Kind := With_Edge; 607 end if; 608 609 -- Add an edge between the withed predecessor unit and the withing 610 -- successor. 611 612 Add_Edge 613 (G => Lib_Graph, 614 Pred => Withed_Vertex, 615 Succ => Succ, 616 Kind => Kind, 617 Activates_Task => False); 618 end Create_With_Edge; 619 620 ----------------------- 621 -- Create_With_Edges -- 622 ----------------------- 623 624 procedure Create_With_Edges (U_Id : Unit_Id) is 625 begin 626 pragma Assert (Present (Lib_Graph)); 627 pragma Assert (Present (U_Id)); 628 629 Create_With_Edges 630 (U_Id => U_Id, 631 Succ => Corresponding_Vertex (Lib_Graph, U_Id)); 632 end Create_With_Edges; 633 634 ----------------------- 635 -- Create_With_Edges -- 636 ----------------------- 637 638 procedure Create_With_Edges 639 (U_Id : Unit_Id; 640 Succ : Library_Graph_Vertex_Id) 641 is 642 pragma Assert (Present (Lib_Graph)); 643 pragma Assert (Present (U_Id)); 644 pragma Assert (Present (Succ)); 645 646 U_Rec : Unit_Record renames ALI.Units.Table (U_Id); 647 648 begin 649 for W_Id in U_Rec.First_With .. U_Rec.Last_With loop 650 if Is_Significant_With (W_Id) then 651 Create_With_Edge (W_Id, Succ); 652 end if; 653 end loop; 654 end Create_With_Edges; 655 656 ------------------ 657 -- Destroy_Unit -- 658 ------------------ 659 660 procedure Destroy_Line_Number (Line : in out Logical_Line_Number) is 661 pragma Unreferenced (Line); 662 begin 663 null; 664 end Destroy_Line_Number; 665 666 -------------------------- 667 -- Duplicate_Unit_Error -- 668 -------------------------- 669 670 procedure Duplicate_Unit_Error 671 (U_Id : Unit_Id; 672 Nam : Unit_Name_Type; 673 Line : Logical_Line_Number) 674 is 675 pragma Assert (Present (U_Id)); 676 pragma Assert (Present (Nam)); 677 678 Prev_Line : constant Logical_Line_Number := 679 Unit_Line_Tables.Get (Unit_To_Line, U_Id); 680 681 begin 682 Error_Msg_Nat_1 := Nat (Line); 683 Error_Msg_Nat_2 := Nat (Prev_Line); 684 Error_Msg_Unit_1 := Nam; 685 686 Error_Msg 687 (Force_Elab_Order_File.all 688 & ":#: duplicate unit name $ from line #"); 689 end Duplicate_Unit_Error; 690 691 --------------- 692 -- Hash_Unit -- 693 --------------- 694 695 function Hash_Unit (U_Id : Unit_Id) return Bucket_Range_Type is 696 begin 697 pragma Assert (Present (U_Id)); 698 699 return Bucket_Range_Type (U_Id); 700 end Hash_Unit; 701 702 ------------------------ 703 -- Internal_Unit_Info -- 704 ------------------------ 705 706 procedure Internal_Unit_Info (Nam : Unit_Name_Type) is 707 begin 708 pragma Assert (Present (Nam)); 709 710 Write_Line 711 ("""" & Get_Name_String (Nam) & """: predefined unit ignored"); 712 end Internal_Unit_Info; 713 714 ----------------------- 715 -- Is_Duplicate_Unit -- 716 ----------------------- 717 718 function Is_Duplicate_Unit (U_Id : Unit_Id) return Boolean is 719 begin 720 pragma Assert (Present (U_Id)); 721 722 return Unit_Line_Tables.Contains (Unit_To_Line, U_Id); 723 end Is_Duplicate_Unit; 724 725 ------------------------- 726 -- Is_Significant_With -- 727 ------------------------- 728 729 function Is_Significant_With (W_Id : With_Id) return Boolean is 730 pragma Assert (Present (W_Id)); 731 732 Withed_Rec : With_Record renames Withs.Table (W_Id); 733 Withed_U_Id : constant Unit_Id := 734 Corresponding_Unit (Withed_Rec.Uname); 735 736 begin 737 -- Nothing to do for a unit which does not exist any more 738 739 if not Present (Withed_U_Id) then 740 return False; 741 742 -- Nothing to do for a limited with 743 744 elsif Withed_Rec.Limited_With then 745 return False; 746 747 -- Nothing to do when the unit does not need to be elaborated 748 749 elsif not Needs_Elaboration (Withed_U_Id) then 750 return False; 751 end if; 752 753 return True; 754 end Is_Significant_With; 755 756 ----------------------- 757 -- Missing_Unit_Info -- 758 ----------------------- 759 760 procedure Missing_Unit_Info (Nam : Unit_Name_Type) is 761 begin 762 pragma Assert (Present (Nam)); 763 764 Write_Line 765 ("""" & Get_Name_String (Nam) & """: not present; ignored"); 766 end Missing_Unit_Info; 767 end Library_Graph_Builders; 768 769end Bindo.Builders; 770