1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
11 -- Copyright (C) 1992-2002 Free Software Foundation, Inc. --
13 -- GNAT is free software; you can redistribute it and/or modify it under --
14 -- terms of the GNU General Public License as published by the Free Soft- --
15 -- ware Foundation; either version 2, or (at your option) any later ver- --
16 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
19 -- for more details. You should have received a copy of the GNU General --
20 -- Public License distributed with GNAT; see file COPYING. If not, write --
21 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
22 -- MA 02111-1307, USA. --
24 -- GNAT was originally developed by the GNAT team at New York University. --
25 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
27 ------------------------------------------------------------------------------
30 with Binde; use Binde;
31 with Butil; use Butil;
32 with Casing; use Casing;
33 with Fname; use Fname;
34 with GNAT.OS_Lib; use GNAT.OS_Lib;
35 with Gnatvsn; use Gnatvsn;
37 with Namet; use Namet;
39 with Osint; use Osint;
40 with Osint.B; use Osint.B;
41 with Output; use Output;
42 with Types; use Types;
43 with Sdefault; use Sdefault;
45 with GNAT.Heap_Sort_A; use GNAT.Heap_Sort_A;
47 package body Bindgen is
49 Statement_Buffer : String (1 .. 1000);
50 -- Buffer used for constructing output statements
53 -- Last location in Statement_Buffer currently set
55 With_DECGNAT : Boolean := False;
56 -- Flag which indicates whether the program uses the DECGNAT library
57 -- (presence of the unit System.Aux_DEC.DECLIB)
59 With_GNARL : Boolean := False;
60 -- Flag which indicates whether the program uses the GNARL library
61 -- (presence of the unit System.OS_Interface)
63 Num_Elab_Calls : Nat := 0;
64 -- Number of generated calls to elaboration routines
66 -----------------------
67 -- Local Subprograms --
68 -----------------------
70 procedure WBI (Info : String) renames Osint.B.Write_Binder_Info;
71 -- Convenient shorthand used throughout
73 procedure Resolve_Binder_Options;
74 -- Set the value of With_GNARL and With_DECGNAT. The latter only on VMS
75 -- since it tests for a package named "dec" which might cause a conflict
76 -- on non-VMS systems.
78 procedure Gen_Adainit_Ada;
79 -- Generates the Adainit procedure (Ada code case)
81 procedure Gen_Adainit_C;
82 -- Generates the Adainit procedure (C code case)
84 procedure Gen_Adafinal_Ada;
85 -- Generate the Adafinal procedure (Ada code case)
87 procedure Gen_Adafinal_C;
88 -- Generate the Adafinal procedure (C code case)
90 procedure Gen_Elab_Calls_Ada;
91 -- Generate sequence of elaboration calls (Ada code case)
93 procedure Gen_Elab_Calls_C;
94 -- Generate sequence of elaboration calls (C code case)
96 procedure Gen_Elab_Order_Ada;
97 -- Generate comments showing elaboration order chosen (Ada case)
99 procedure Gen_Elab_Order_C;
100 -- Generate comments showing elaboration order chosen (C case)
102 procedure Gen_Elab_Defs_C;
103 -- Generate sequence of definitions for elaboration routines (C code case)
105 procedure Gen_Exception_Table_Ada;
106 -- Generate binder exception table (Ada code case). This consists of
107 -- declarations followed by a begin followed by a call. If zero cost
108 -- exceptions are not active, then only the begin is generated.
110 procedure Gen_Exception_Table_C;
111 -- Generate binder exception table (C code case). This has no effect
112 -- if zero cost exceptions are not active, otherwise it generates a
113 -- set of declarations followed by a call.
115 procedure Gen_Main_Ada;
116 -- Generate procedure main (Ada code case)
118 procedure Gen_Main_C;
119 -- Generate main() procedure (C code case)
121 procedure Gen_Object_Files_Options;
122 -- Output comments containing a list of the full names of the object
123 -- files to be linked and the list of linker options supplied by
124 -- Linker_Options pragmas in the source. (C and Ada code case)
126 procedure Gen_Output_File_Ada (Filename : String);
127 -- Generate output file (Ada code case)
129 procedure Gen_Output_File_C (Filename : String);
130 -- Generate output file (C code case)
132 procedure Gen_Scalar_Values;
133 -- Generates scalar initialization values for -Snn. A single procedure
134 -- handles both the Ada and C cases, since there is much common code.
136 procedure Gen_Versions_Ada;
137 -- Output series of definitions for unit versions (Ada code case)
139 procedure Gen_Versions_C;
140 -- Output series of definitions for unit versions (C code case)
142 function Get_Ada_Main_Name return String;
143 -- This function is used in the Ada main output case to compute a usable
144 -- name for the generated main program. The normal main program name is
145 -- Ada_Main, but this won't work if the user has a unit with this name.
146 -- This function tries Ada_Main first, and if there is such a clash, then
147 -- it tries Ada_Name_01, Ada_Name_02 ... Ada_Name_99 in sequence.
149 function Get_Main_Name return String;
150 -- This function is used in the Ada main output case to compute the
151 -- correct external main program. It is "main" by default, except on
152 -- VxWorks where it is the name of the Ada main name without the "_ada".
153 -- the -Mname binder option overrides the default with name.
155 function Lt_Linker_Option (Op1, Op2 : Natural) return Boolean;
156 -- Compare linker options, when sorting, first according to
157 -- Is_Internal_File (internal files come later) and then by
158 -- elaboration order position (latest to earliest).
160 procedure Move_Linker_Option (From : Natural; To : Natural);
161 -- Move routine for sorting linker options
163 procedure Public_Version_Warning;
164 -- Emit a warning concerning the use of the Public version under
165 -- certain circumstances. See details in body.
167 procedure Set_Char (C : Character);
168 -- Set given character in Statement_Buffer at the Last + 1 position
169 -- and increment Last by one to reflect the stored character.
171 procedure Set_Int (N : Int);
172 -- Set given value in decimal in Statement_Buffer with no spaces
173 -- starting at the Last + 1 position, and updating Last past the value.
174 -- A minus sign is output for a negative value.
176 procedure Set_Main_Program_Name;
177 -- Given the main program name in Name_Buffer (length in Name_Len)
178 -- generate the name of the routine to be used in the call. The name
179 -- is generated starting at Last + 1, and Last is updated past it.
181 procedure Set_Name_Buffer;
182 -- Set the value stored in positions 1 .. Name_Len of the Name_Buffer.
184 procedure Set_String (S : String);
185 -- Sets characters of given string in Statement_Buffer, starting at the
186 -- Last + 1 position, and updating last past the string value.
188 procedure Set_Unit_Name;
189 -- Given a unit name in the Name_Buffer, copies it to Statement_Buffer,
190 -- starting at the Last + 1 position, and updating last past the value.
191 -- changing periods to double underscores, and updating Last appropriately.
193 procedure Set_Unit_Number (U : Unit_Id);
194 -- Sets unit number (first unit is 1, leading zeroes output to line
195 -- up all output unit numbers nicely as required by the value, and
196 -- by the total number of units.
198 procedure Tab_To (N : Natural);
199 -- If Last is greater than or equal to N, no effect, otherwise store
200 -- blanks in Statement_Buffer bumping Last, until Last = N.
202 procedure Write_Info_Ada_C (Ada : String; C : String; Common : String);
203 -- For C code case, write C & Common, for Ada case write Ada & Common
204 -- to current binder output file using Write_Binder_Info.
206 procedure Write_Statement_Buffer;
207 -- Write out contents of statement buffer up to Last, and reset Last to 0
209 procedure Write_Statement_Buffer (S : String);
210 -- First writes its argument (using Set_String (S)), then writes out the
211 -- contents of statement buffer up to Last, and reset Last to 0
213 ----------------------
214 -- Gen_Adafinal_Ada --
215 ----------------------
217 procedure Gen_Adafinal_Ada is
220 WBI (" procedure " & Ada_Final_Name.all & " is");
223 -- If compiling for the JVM, we directly call Adafinal because
224 -- we don't import it via Do_Finalize (see Gen_Output_File_Ada).
226 if Hostparm.Java_VM then
227 WBI (" System.Standard_Library.Adafinal;");
229 WBI (" Do_Finalize;");
232 WBI (" end " & Ada_Final_Name.all & ";");
233 end Gen_Adafinal_Ada;
239 procedure Gen_Adafinal_C is
241 WBI ("void " & Ada_Final_Name.all & " () {");
242 WBI (" system__standard_library__adafinal ();");
247 ---------------------
248 -- Gen_Adainit_Ada --
249 ---------------------
251 procedure Gen_Adainit_Ada is
252 Main_Priority : Int renames ALIs.Table (ALIs.First).Main_Priority;
255 WBI (" procedure " & Ada_Init_Name.all & " is");
257 -- Generate externals for elaboration entities
259 for E in Elab_Order.First .. Elab_Order.Last loop
261 Unum : constant Unit_Id := Elab_Order.Table (E);
262 U : Unit_Record renames Units.Table (Unum);
265 if U.Set_Elab_Entity then
268 Set_Unit_Number (Unum);
269 Set_String (" : Boolean; pragma Import (Ada, ");
271 Set_Unit_Number (Unum);
273 Get_Name_String (U.Uname);
275 -- In the case of JGNAT we need to emit an Import name
276 -- that includes the class name (using '$' separators
277 -- in the case of a child unit name).
279 if Hostparm.Java_VM then
280 for J in 1 .. Name_Len - 2 loop
281 if Name_Buffer (J) /= '.' then
282 Set_Char (Name_Buffer (J));
290 -- If the unit name is very long, then split the
291 -- Import link name across lines using "&" (occurs
292 -- in some C2 tests).
294 if 2 * Name_Len + 60 > Hostparm.Max_Line_Length then
296 Write_Statement_Buffer;
302 Set_String ("_E"");");
303 Write_Statement_Buffer;
308 Write_Statement_Buffer;
310 -- Case of No_Run_Time mode. The only global variable that might
311 -- be needed (by the Ravenscar profile) is the priority of the
312 -- environment. Also no exception tables are needed.
314 if No_Run_Time_Specified then
315 if Main_Priority /= No_Main_Priority then
316 WBI (" Main_Priority : Integer;");
317 WBI (" pragma Import (C, Main_Priority," &
318 " ""__gl_main_priority"");");
324 if Main_Priority /= No_Main_Priority then
325 Set_String (" Main_Priority := ");
326 Set_Int (Main_Priority);
328 Write_Statement_Buffer;
334 -- Normal case (not No_Run_Time mode). The global values are
335 -- assigned using the runtime routine Set_Globals (we have to use
336 -- the routine call, rather than define the globals in the binder
337 -- file to deal with cross-library calls in some systems.
340 -- Generate restrictions string
342 Set_String (" Restrictions : constant String :=");
343 Write_Statement_Buffer;
346 for J in Restrictions'Range loop
347 Set_Char (Restrictions (J));
351 Write_Statement_Buffer;
354 WBI (" procedure Set_Globals");
355 WBI (" (Main_Priority : Integer;");
356 WBI (" Time_Slice_Value : Integer;");
357 WBI (" WC_Encoding : Character;");
358 WBI (" Locking_Policy : Character;");
359 WBI (" Queuing_Policy : Character;");
360 WBI (" Task_Dispatching_Policy : Character;");
361 WBI (" Restrictions : System.Address;");
362 WBI (" Unreserve_All_Interrupts : Integer;");
363 WBI (" Exception_Tracebacks : Integer;");
364 WBI (" Zero_Cost_Exceptions : Integer);");
365 WBI (" pragma Import (C, Set_Globals, ""__gnat_set_globals"");");
367 -- Import entry point for elaboration time signal handler
368 -- installation, and indication of whether it's been called
372 WBI (" procedure Install_Handler;");
373 WBI (" pragma Import (C, Install_Handler, " &
374 """__gnat_install_handler"");");
376 WBI (" Handler_Installed : Integer;");
377 WBI (" pragma Import (C, Handler_Installed, " &
378 """__gnat_handler_installed"");");
380 -- Generate exception table
382 Gen_Exception_Table_Ada;
384 -- Generate the call to Set_Globals
386 WBI (" Set_Globals");
388 Set_String (" (Main_Priority => ");
389 Set_Int (Main_Priority);
391 Write_Statement_Buffer;
393 Set_String (" Time_Slice_Value => ");
395 if Task_Dispatching_Policy_Specified = 'F'
396 and then ALIs.Table (ALIs.First).Time_Slice_Value = -1
400 Set_Int (ALIs.Table (ALIs.First).Time_Slice_Value);
404 Write_Statement_Buffer;
406 Set_String (" WC_Encoding => '");
407 Set_Char (ALIs.Table (ALIs.First).WC_Encoding);
409 Write_Statement_Buffer;
411 Set_String (" Locking_Policy => '");
412 Set_Char (Locking_Policy_Specified);
414 Write_Statement_Buffer;
416 Set_String (" Queuing_Policy => '");
417 Set_Char (Queuing_Policy_Specified);
419 Write_Statement_Buffer;
421 Set_String (" Task_Dispatching_Policy => '");
422 Set_Char (Task_Dispatching_Policy_Specified);
424 Write_Statement_Buffer;
426 WBI (" Restrictions => Restrictions'Address,");
428 Set_String (" Unreserve_All_Interrupts => ");
430 if Unreserve_All_Interrupts_Specified then
437 Write_Statement_Buffer;
439 Set_String (" Exception_Tracebacks => ");
441 if Exception_Tracebacks then
448 Write_Statement_Buffer;
450 Set_String (" Zero_Cost_Exceptions => ");
452 if Zero_Cost_Exceptions_Specified then
459 Write_Statement_Buffer;
461 -- Generate call to Install_Handler
463 WBI (" if Handler_Installed = 0 then");
464 WBI (" Install_Handler;");
470 WBI (" end " & Ada_Init_Name.all & ";");
477 procedure Gen_Adainit_C is
478 Main_Priority : Int renames ALIs.Table (ALIs.First).Main_Priority;
481 WBI ("void " & Ada_Init_Name.all & " ()");
484 -- Generate externals for elaboration entities
486 for E in Elab_Order.First .. Elab_Order.Last loop
488 Unum : constant Unit_Id := Elab_Order.Table (E);
489 U : Unit_Record renames Units.Table (Unum);
492 if U.Set_Elab_Entity then
493 Set_String (" extern char ");
494 Get_Name_String (U.Uname);
497 Write_Statement_Buffer;
502 Write_Statement_Buffer;
506 if No_Run_Time_Specified then
508 -- Case of No_Run_Time mode. Set __gl_main_priority if needed
509 -- for the Ravenscar profile.
511 if Main_Priority /= No_Main_Priority then
512 Set_String (" extern int __gl_main_priority = ");
513 Set_Int (Main_Priority);
515 Write_Statement_Buffer;
518 -- Normal case (run time present)
521 -- Generate definition for restrictions string
523 Set_String (" const char *restrictions = """);
525 for J in Restrictions'Range loop
526 Set_Char (Restrictions (J));
530 Write_Statement_Buffer;
532 -- Code for normal case (not in No_Run_Time mode)
534 Gen_Exception_Table_C;
536 -- Generate call to set the runtime global variables defined in
537 -- a-init.c. We define the varables in a-init.c, rather than in
538 -- the binder generated file itself to avoid undefined externals
539 -- when the runtime is linked as a shareable image library.
541 -- We call the routine from inside adainit() because this works for
542 -- both programs with and without binder generated "main" functions.
544 WBI (" __gnat_set_globals (");
547 Set_Int (Main_Priority);
550 Set_String ("/* Main_Priority */");
551 Write_Statement_Buffer;
555 if Task_Dispatching_Policy = 'F'
556 and then ALIs.Table (ALIs.First).Time_Slice_Value = -1
560 Set_Int (ALIs.Table (ALIs.First).Time_Slice_Value);
565 Set_String ("/* Time_Slice_Value */");
566 Write_Statement_Buffer;
569 Set_Char (ALIs.Table (ALIs.First).WC_Encoding);
572 Set_String ("/* WC_Encoding */");
573 Write_Statement_Buffer;
576 Set_Char (Locking_Policy_Specified);
579 Set_String ("/* Locking_Policy */");
580 Write_Statement_Buffer;
583 Set_Char (Queuing_Policy_Specified);
586 Set_String ("/* Queuing_Policy */");
587 Write_Statement_Buffer;
590 Set_Char (Task_Dispatching_Policy_Specified);
593 Set_String ("/* Tasking_Dispatching_Policy */");
594 Write_Statement_Buffer;
597 Set_String ("restrictions");
600 Set_String ("/* Restrictions */");
601 Write_Statement_Buffer;
604 Set_Int (Boolean'Pos (Unreserve_All_Interrupts_Specified));
607 Set_String ("/* Unreserve_All_Interrupts */");
608 Write_Statement_Buffer;
611 Set_Int (Boolean'Pos (Exception_Tracebacks));
614 Set_String ("/* Exception_Tracebacks */");
615 Write_Statement_Buffer;
618 Set_Int (Boolean'Pos (Zero_Cost_Exceptions_Specified));
621 Set_String ("/* Zero_Cost_Exceptions */");
622 Write_Statement_Buffer;
624 -- Install elaboration time signal handler
626 WBI (" if (__gnat_handler_installed == 0)");
628 WBI (" __gnat_install_handler ();");
637 ------------------------
638 -- Gen_Elab_Calls_Ada --
639 ------------------------
641 procedure Gen_Elab_Calls_Ada is
644 for E in Elab_Order.First .. Elab_Order.Last loop
646 Unum : constant Unit_Id := Elab_Order.Table (E);
647 U : Unit_Record renames Units.Table (Unum);
650 -- This is the unit number of the spec that corresponds to
651 -- this entry. It is the same as Unum except when the body
652 -- and spec are different and we are currently processing
653 -- the body, in which case it is the spec (Unum + 1).
656 if U.Utype = Is_Body then
657 Unum_Spec := Unum + 1;
662 -- Case of no elaboration code
666 -- The only case in which we have to do something is if
667 -- this is a body, with a separate spec, where the separate
668 -- spec has an elaboration entity defined.
670 -- In that case, this is where we set the elaboration entity
671 -- to True, we do not need to test if this has already been
672 -- done, since it is quicker to set the flag than to test it.
675 and then Units.Table (Unum_Spec).Set_Elab_Entity
678 Set_Unit_Number (Unum_Spec);
679 Set_String (" := True;");
680 Write_Statement_Buffer;
683 -- Here if elaboration code is present. We generate:
685 -- if not uname_E then
686 -- uname'elab_[spec|body];
690 -- The uname_E assignment is skipped if this is a separate spec,
691 -- since the assignment will be done when we process the body.
694 Set_String (" if not E");
695 Set_Unit_Number (Unum_Spec);
696 Set_String (" then");
697 Write_Statement_Buffer;
700 Get_Decoded_Name_String_With_Brackets (U.Uname);
702 if Name_Buffer (Name_Len) = 's' then
703 Name_Buffer (Name_Len - 1 .. Name_Len + 8) := "'elab_spec";
705 Name_Buffer (Name_Len - 1 .. Name_Len + 8) := "'elab_body";
708 Name_Len := Name_Len + 8;
709 Set_Casing (U.Icasing);
712 Write_Statement_Buffer;
714 if U.Utype /= Is_Spec then
716 Set_Unit_Number (Unum_Spec);
717 Set_String (" := True;");
718 Write_Statement_Buffer;
726 end Gen_Elab_Calls_Ada;
728 ----------------------
729 -- Gen_Elab_Calls_C --
730 ----------------------
732 procedure Gen_Elab_Calls_C is
735 for E in Elab_Order.First .. Elab_Order.Last loop
737 Unum : constant Unit_Id := Elab_Order.Table (E);
738 U : Unit_Record renames Units.Table (Unum);
741 -- This is the unit number of the spec that corresponds to
742 -- this entry. It is the same as Unum except when the body
743 -- and spec are different and we are currently processing
744 -- the body, in which case it is the spec (Unum + 1).
747 if U.Utype = Is_Body then
748 Unum_Spec := Unum + 1;
753 -- Case of no elaboration code
757 -- The only case in which we have to do something is if
758 -- this is a body, with a separate spec, where the separate
759 -- spec has an elaboration entity defined.
761 -- In that case, this is where we set the elaboration entity
762 -- to True, we do not need to test if this has already been
763 -- done, since it is quicker to set the flag than to test it.
766 and then Units.Table (Unum_Spec).Set_Elab_Entity
769 Get_Name_String (U.Uname);
771 Set_String ("_E = 1;");
772 Write_Statement_Buffer;
775 -- Here if elaboration code is present. We generate:
777 -- if (uname_E == 0) {
778 -- uname__elab[s|b] ();
782 -- The uname_E assignment is skipped if this is a separate spec,
783 -- since the assignment will be done when we process the body.
786 Set_String (" if (");
787 Get_Name_String (U.Uname);
789 Set_String ("_E == 0) {");
790 Write_Statement_Buffer;
794 Set_String ("___elab");
795 Set_Char (Name_Buffer (Name_Len)); -- 's' or 'b' for spec/body
797 Write_Statement_Buffer;
799 if U.Utype /= Is_Spec then
802 Set_String ("_E++;");
803 Write_Statement_Buffer;
811 end Gen_Elab_Calls_C;
813 ----------------------
814 -- Gen_Elab_Defs_C --
815 ----------------------
817 procedure Gen_Elab_Defs_C is
819 for E in Elab_Order.First .. Elab_Order.Last loop
821 -- Generate declaration of elaboration procedure if elaboration
822 -- needed. Note that passive units are always excluded.
824 if not Units.Table (Elab_Order.Table (E)).No_Elab then
825 Get_Name_String (Units.Table (Elab_Order.Table (E)).Uname);
826 Set_String ("extern void ");
828 Set_String ("___elab");
829 Set_Char (Name_Buffer (Name_Len)); -- 's' or 'b' for spec/body
830 Set_String (" PARAMS ((void));");
831 Write_Statement_Buffer;
839 ------------------------
840 -- Gen_Elab_Order_Ada --
841 ------------------------
843 procedure Gen_Elab_Order_Ada is
846 WBI (" -- BEGIN ELABORATION ORDER");
848 for J in Elab_Order.First .. Elab_Order.Last loop
850 Get_Unit_Name_String (Units.Table (Elab_Order.Table (J)).Uname);
852 Write_Statement_Buffer;
855 WBI (" -- END ELABORATION ORDER");
856 end Gen_Elab_Order_Ada;
858 ----------------------
859 -- Gen_Elab_Order_C --
860 ----------------------
862 procedure Gen_Elab_Order_C is
865 WBI ("/* BEGIN ELABORATION ORDER");
867 for J in Elab_Order.First .. Elab_Order.Last loop
868 Get_Unit_Name_String (Units.Table (Elab_Order.Table (J)).Uname);
870 Write_Statement_Buffer;
873 WBI (" END ELABORATION ORDER */");
874 end Gen_Elab_Order_C;
876 -----------------------------
877 -- Gen_Exception_Table_Ada --
878 -----------------------------
880 procedure Gen_Exception_Table_Ada is
882 Last : ALI_Id := No_ALI_Id;
885 if not Zero_Cost_Exceptions_Specified then
890 -- The code we generate looks like
892 -- procedure SDP_Table_Build
893 -- (SDP_Addresses : System.Address;
894 -- SDP_Count : Natural;
895 -- Elab_Addresses : System.Address;
896 -- Elab_Addr_Count : Natural);
897 -- pragma Import (C, SDP_Table_Build, "__gnat_SDP_Table_Build");
899 -- ST : aliased constant array (1 .. nnn) of System.Address := (
900 -- unit_name_1'UET_Address,
901 -- unit_name_2'UET_Address,
903 -- unit_name_3'UET_Address,
905 -- EA : aliased constant array (1 .. eee) of System.Address := (
906 -- adainit'Code_Address,
907 -- adafinal'Code_Address,
908 -- unit_name'elab[spec|body]'Code_Address,
909 -- unit_name'elab[spec|body]'Code_Address,
910 -- unit_name'elab[spec|body]'Code_Address,
911 -- unit_name'elab[spec|body]'Code_Address);
914 -- SDP_Table_Build (ST'Address, nnn, EA'Address, eee);
917 for A in ALIs.First .. ALIs.Last loop
918 if ALIs.Table (A).Unit_Exception_Table then
926 -- Happens with "gnatmake -a -f -gnatL ..."
933 WBI (" procedure SDP_Table_Build");
934 WBI (" (SDP_Addresses : System.Address;");
935 WBI (" SDP_Count : Natural;");
936 WBI (" Elab_Addresses : System.Address;");
937 WBI (" Elab_Addr_Count : Natural);");
939 "pragma Import (C, SDP_Table_Build, ""__gnat_SDP_Table_Build"");");
942 Set_String (" ST : aliased constant array (1 .. ");
944 Set_String (") of System.Address := (");
947 Set_String ("1 => A1);");
948 Write_Statement_Buffer;
951 Write_Statement_Buffer;
953 for A in ALIs.First .. ALIs.Last loop
954 if ALIs.Table (A).Unit_Exception_Table then
955 Get_Decoded_Name_String_With_Brackets
956 (Units.Table (ALIs.Table (A).First_Unit).Uname);
957 Set_Casing (Mixed_Case);
959 Set_String (Name_Buffer (1 .. Name_Len - 2));
960 Set_String ("'UET_Address");
968 Write_Statement_Buffer;
974 Set_String (" EA : aliased constant array (1 .. ");
975 Set_Int (Num_Elab_Calls + 2);
976 Set_String (") of System.Address := (");
977 Write_Statement_Buffer;
978 WBI (" " & Ada_Init_Name.all & "'Code_Address,");
980 -- If compiling for the JVM, we directly reference Adafinal because
981 -- we don't import it via Do_Finalize (see Gen_Output_File_Ada).
983 if Hostparm.Java_VM then
984 Set_String (" System.Standard_Library.Adafinal'Code_Address");
986 Set_String (" Do_Finalize'Code_Address");
989 for E in Elab_Order.First .. Elab_Order.Last loop
990 Get_Decoded_Name_String_With_Brackets
991 (Units.Table (Elab_Order.Table (E)).Uname);
993 if Units.Table (Elab_Order.Table (E)).No_Elab then
998 Write_Statement_Buffer;
1001 if Name_Buffer (Name_Len) = 's' then
1002 Name_Buffer (Name_Len - 1 .. Name_Len + 21) :=
1003 "'elab_spec'code_address";
1005 Name_Buffer (Name_Len - 1 .. Name_Len + 21) :=
1006 "'elab_body'code_address";
1009 Name_Len := Name_Len + 21;
1010 Set_Casing (Units.Table (Elab_Order.Table (E)).Icasing);
1016 Write_Statement_Buffer;
1021 Set_String (" SDP_Table_Build (ST'Address, ");
1023 Set_String (", EA'Address, ");
1024 Set_Int (Num_Elab_Calls + 2);
1026 Write_Statement_Buffer;
1027 end Gen_Exception_Table_Ada;
1029 ---------------------------
1030 -- Gen_Exception_Table_C --
1031 ---------------------------
1033 procedure Gen_Exception_Table_C is
1038 if not Zero_Cost_Exceptions_Specified then
1042 -- The code we generate looks like
1044 -- extern void *__gnat_unitname1__SDP;
1045 -- extern void *__gnat_unitname2__SDP;
1048 -- void **st[nnn] = {
1049 -- &__gnat_unitname1__SDP,
1050 -- &__gnat_unitname2__SDP,
1052 -- &__gnat_unitnamen__SDP};
1054 -- extern void unitname1__elabb ();
1055 -- extern void unitname2__elabb ();
1058 -- void (*ea[eee]) () = {
1061 -- unitname1___elab[b,s],
1062 -- unitname2___elab[b,s],
1064 -- unitnamen___elab[b,s]};
1066 -- __gnat_SDP_Table_Build (&st, nnn, &ea, eee);
1069 for A in ALIs.First .. ALIs.Last loop
1070 if ALIs.Table (A).Unit_Exception_Table then
1073 Set_String (" extern void *__gnat_");
1074 Get_Name_String (Units.Table (ALIs.Table (A).First_Unit).Uname);
1076 Set_String ("__SDP");
1078 Write_Statement_Buffer;
1084 -- Happens with "gnatmake -a -f -gnatL ..."
1091 Set_String (" void **st[");
1093 Set_String ("] = {");
1094 Write_Statement_Buffer;
1097 for A in ALIs.First .. ALIs.Last loop
1098 if ALIs.Table (A).Unit_Exception_Table then
1101 Set_String (" &__gnat_");
1102 Get_Name_String (Units.Table (ALIs.Table (A).First_Unit).Uname);
1104 Set_String ("__SDP");
1112 Write_Statement_Buffer;
1117 for E in Elab_Order.First .. Elab_Order.Last loop
1118 Get_Name_String (Units.Table (Elab_Order.Table (E)).Uname);
1120 if Units.Table (Elab_Order.Table (E)).No_Elab then
1124 Set_String (" extern void ");
1126 Set_String ("___elab");
1127 Set_Char (Name_Buffer (Name_Len)); -- 's' or 'b' for spec/body
1128 Set_String (" ();");
1129 Write_Statement_Buffer;
1134 Set_String (" void (*ea[");
1135 Set_Int (Num_Elab_Calls + 2);
1136 Set_String ("]) () = {");
1137 Write_Statement_Buffer;
1139 WBI (" " & Ada_Init_Name.all & ",");
1140 Set_String (" system__standard_library__adafinal");
1142 for E in Elab_Order.First .. Elab_Order.Last loop
1143 Get_Name_String (Units.Table (Elab_Order.Table (E)).Uname);
1145 if Units.Table (Elab_Order.Table (E)).No_Elab then
1150 Write_Statement_Buffer;
1153 Set_String ("___elab");
1154 Set_Char (Name_Buffer (Name_Len)); -- 's' or 'b' for spec/body
1159 Write_Statement_Buffer;
1163 Set_String (" __gnat_SDP_Table_Build (&st, ");
1165 Set_String (", ea, ");
1166 Set_Int (Num_Elab_Calls + 2);
1168 Write_Statement_Buffer;
1169 end Gen_Exception_Table_C;
1175 procedure Gen_Main_Ada is
1176 Target : constant String_Ptr := Target_Name;
1177 VxWorks_Target : constant Boolean :=
1178 Target (Target'Last - 7 .. Target'Last) = "vxworks/"
1179 or else Target (Target'Last - 9 .. Target'Last) = "vxworksae/";
1183 Set_String (" function ");
1184 Set_String (Get_Main_Name);
1186 if VxWorks_Target then
1187 Set_String (" return Integer is");
1188 Write_Statement_Buffer;
1191 Write_Statement_Buffer;
1192 WBI (" (argc : Integer;");
1193 WBI (" argv : System.Address;");
1194 WBI (" envp : System.Address)");
1195 WBI (" return Integer");
1199 -- Initialize and Finalize are not used in No_Run_Time mode
1201 if not No_Run_Time_Specified then
1202 WBI (" procedure initialize;");
1203 WBI (" pragma Import (C, initialize, ""__gnat_initialize"");");
1205 WBI (" procedure finalize;");
1206 WBI (" pragma Import (C, finalize, ""__gnat_finalize"");");
1210 -- Deal with declarations for main program case
1212 if not No_Main_Subprogram then
1214 -- To call the main program, we declare it using a pragma Import
1215 -- Ada with the right link name.
1217 -- It might seem more obvious to "with" the main program, and call
1218 -- it in the normal Ada manner. We do not do this for three reasons:
1220 -- 1. It is more efficient not to recompile the main program
1221 -- 2. We are not entitled to assume the source is accessible
1222 -- 3. We don't know what options to use to compile it
1224 -- It is really reason 3 that is most critical (indeed we used
1225 -- to generate the "with", but several regression tests failed).
1229 if ALIs.Table (ALIs.First).Main_Program = Func then
1230 WBI (" Result : Integer;");
1232 WBI (" function Ada_Main_Program return Integer;");
1235 WBI (" procedure Ada_Main_Program;");
1238 Set_String (" pragma Import (Ada, Ada_Main_Program, """);
1239 Get_Name_String (Units.Table (First_Unit_Entry).Uname);
1240 Set_Main_Program_Name;
1241 Set_String (""");");
1243 Write_Statement_Buffer;
1247 -- Generate a reference to Ada_Main_Program_Name. This symbol is
1248 -- not referenced elsewhere in the generated program, but is needed
1249 -- by the debugger (that's why it is generated in the first place).
1250 -- The reference stops Ada_Main_Program_Name from being optimized
1251 -- away by smart linkers, such as the AiX linker.
1253 if Bind_Main_Program then
1255 (" Ensure_Reference : System.Address := " &
1256 "Ada_Main_Program_Name'Address;");
1262 -- On VxWorks, there are no command line arguments
1264 if VxWorks_Target then
1265 WBI (" gnat_argc := 0;");
1266 WBI (" gnat_argv := System.Null_Address;");
1267 WBI (" gnat_envp := System.Null_Address;");
1269 -- Normal case of command line arguments present
1272 WBI (" gnat_argc := argc;");
1273 WBI (" gnat_argv := argv;");
1274 WBI (" gnat_envp := envp;");
1278 if not No_Run_Time_Specified then
1279 WBI (" Initialize;");
1282 WBI (" " & Ada_Init_Name.all & ";");
1284 if not No_Main_Subprogram then
1285 WBI (" Break_Start;");
1287 if ALIs.Table (ALIs.First).Main_Program = Proc then
1288 WBI (" Ada_Main_Program;");
1290 WBI (" Result := Ada_Main_Program;");
1294 -- Adafinal is only called if we have a run time
1296 if not No_Run_Time_Specified then
1298 -- If compiling for the JVM, we directly call Adafinal because
1299 -- we don't import it via Do_Finalize (see Gen_Output_File_Ada).
1301 if Hostparm.Java_VM then
1302 WBI (" System.Standard_Library.Adafinal;");
1304 WBI (" Do_Finalize;");
1308 -- Finalize is only called if we have a run time
1310 if not No_Run_Time_Specified then
1316 if No_Main_Subprogram
1317 or else ALIs.Table (ALIs.First).Main_Program = Proc
1319 WBI (" return (gnat_exit_status);");
1321 WBI (" return (Result);");
1331 procedure Gen_Main_C is
1332 Target : constant String_Ptr := Target_Name;
1333 VxWorks_Target : constant Boolean :=
1334 Target (Target'Last - 7 .. Target'Last) = "vxworks/"
1335 or else Target (Target'Last - 9 .. Target'Last) = "vxworksae/";
1338 Set_String ("int ");
1339 Set_String (Get_Main_Name);
1341 -- On VxWorks, there are no command line arguments
1343 if VxWorks_Target then
1346 -- Normal case with command line arguments present
1349 Set_String (" (argc, argv, envp)");
1352 Write_Statement_Buffer;
1354 -- VxWorks doesn't have the notion of argc/argv
1356 if VxWorks_Target then
1358 WBI (" int result;");
1359 WBI (" gnat_argc = 0;");
1360 WBI (" gnat_argv = 0;");
1361 WBI (" gnat_envp = 0;");
1363 -- Normal case of arguments present
1367 WBI (" char **argv;");
1368 WBI (" char **envp;");
1371 -- Generate a reference to __gnat_ada_main_program_name. This symbol
1372 -- is not referenced elsewhere in the generated program, but is
1373 -- needed by the debugger (that's why it is generated in the first
1374 -- place). The reference stops Ada_Main_Program_Name from being
1375 -- optimized away by smart linkers, such as the AiX linker.
1377 if Bind_Main_Program then
1378 WBI (" char *ensure_reference = __gnat_ada_main_program_name;");
1382 if ALIs.Table (ALIs.First).Main_Program = Func then
1383 WBI (" int result;");
1386 WBI (" gnat_argc = argc;");
1387 WBI (" gnat_argv = argv;");
1388 WBI (" gnat_envp = envp;");
1392 -- The __gnat_initialize routine is used only if we have a run-time
1394 if not No_Run_Time_Specified then
1396 (" __gnat_initialize ();");
1399 WBI (" " & Ada_Init_Name.all & " ();");
1401 if not No_Main_Subprogram then
1403 WBI (" __gnat_break_start ();");
1406 -- Output main program name
1408 Get_Name_String (Units.Table (First_Unit_Entry).Uname);
1410 -- Main program is procedure case
1412 if ALIs.Table (ALIs.First).Main_Program = Proc then
1414 Set_Main_Program_Name;
1415 Set_String (" ();");
1416 Write_Statement_Buffer;
1418 -- Main program is function case
1420 else -- ALIs.Table (ALIs_First).Main_Program = Func
1421 Set_String (" result = ");
1422 Set_Main_Program_Name;
1423 Set_String (" ();");
1424 Write_Statement_Buffer;
1429 -- Adafinal is called only when we have a run-time
1431 if not No_Run_Time_Specified then
1433 WBI (" system__standard_library__adafinal ();");
1436 -- The finalize routine is used only if we have a run-time
1438 if not No_Run_Time_Specified then
1439 WBI (" __gnat_finalize ();");
1442 if ALIs.Table (ALIs.First).Main_Program = Func then
1444 if Hostparm.OpenVMS then
1446 -- VMS must use the Posix exit routine in order to get an
1447 -- Unix compatible exit status.
1449 WBI (" __posix_exit (result);");
1452 WBI (" exit (result);");
1457 if Hostparm.OpenVMS then
1458 -- VMS must use the Posix exit routine in order to get an
1459 -- Unix compatible exit status.
1460 WBI (" __posix_exit (gnat_exit_status);");
1462 WBI (" exit (gnat_exit_status);");
1469 ------------------------------
1470 -- Gen_Object_Files_Options --
1471 ------------------------------
1473 procedure Gen_Object_Files_Options is
1475 -- This keeps track of the position in the sorted set of entries
1476 -- in the Linker_Options table of where the first entry from an
1477 -- internal file appears.
1479 procedure Write_Linker_Option;
1480 -- Write binder info linker option.
1482 -------------------------
1483 -- Write_Linker_Option --
1484 -------------------------
1486 procedure Write_Linker_Option is
1491 -- Loop through string, breaking at null's
1494 while Start < Name_Len loop
1496 -- Find null ending this section
1499 while Name_Buffer (Stop) /= ASCII.NUL
1500 and then Stop <= Name_Len loop
1504 -- Process section if non-null
1506 if Stop > Start then
1507 if Output_Linker_Option_List then
1508 Write_Str (Name_Buffer (Start .. Stop - 1));
1512 (" -- ", "", Name_Buffer (Start .. Stop - 1));
1517 end Write_Linker_Option;
1519 -- Start of processing for Gen_Object_Files_Options
1523 Write_Info_Ada_C ("--", "/*", " BEGIN Object file/option list");
1525 for E in Elab_Order.First .. Elab_Order.Last loop
1527 -- If not spec that has an associated body, then generate a
1528 -- comment giving the name of the corresponding object file.
1530 if Units.Table (Elab_Order.Table (E)).Utype /= Is_Spec then
1533 (Units.Table (Elab_Order.Table (E)).My_ALI).Ofile_Full_Name);
1535 -- If the presence of an object file is necessary or if it
1536 -- exists, then use it.
1538 if not Hostparm.Exclude_Missing_Objects
1540 GNAT.OS_Lib.Is_Regular_File (Name_Buffer (1 .. Name_Len))
1542 Write_Info_Ada_C (" -- ", "", Name_Buffer (1 .. Name_Len));
1543 if Output_Object_List then
1544 Write_Str (Name_Buffer (1 .. Name_Len));
1548 -- Don't link with the shared library on VMS if an internal
1549 -- filename object is seen. Multiply defined symbols will
1553 and then Is_Internal_File_Name
1555 (Units.Table (Elab_Order.Table (E)).My_ALI).Sfile)
1557 Opt.Shared_Libgnat := False;
1564 -- Add a "-Ldir" for each directory in the object path. We skip this
1565 -- in No_Run_Time mode, where we want more precise control of exactly
1566 -- what goes into the resulting object file
1568 if not No_Run_Time_Specified then
1569 for J in 1 .. Nb_Dir_In_Obj_Search_Path loop
1571 Dir : String_Ptr := Dir_In_Obj_Search_Path (J);
1575 Add_Str_To_Name_Buffer ("-L");
1576 Add_Str_To_Name_Buffer (Dir.all);
1577 Write_Linker_Option;
1582 -- Sort linker options
1584 -- This sort accomplishes two important purposes:
1586 -- a) All application files are sorted to the front, and all
1587 -- GNAT internal files are sorted to the end. This results
1588 -- in a well defined dividing line between the two sets of
1589 -- files, for the purpose of inserting certain standard
1590 -- library references into the linker arguments list.
1592 -- b) Given two different units, we sort the linker options so
1593 -- that those from a unit earlier in the elaboration order
1594 -- comes later in the list. This is a heuristic designed
1595 -- to create a more friendly order of linker options when
1596 -- the operations appear in separate units. The idea is that
1597 -- if unit A must be elaborated before unit B, then it is
1598 -- more likely that B references libraries included by A,
1599 -- than vice versa, so we want the libraries included by
1600 -- A to come after the libraries included by B.
1602 -- These two criteria are implemented by function Lt_Linker_Option.
1603 -- Note that a special case of b) is that specs are elaborated before
1604 -- bodies, so linker options from specs come after linker options
1605 -- for bodies, and again, the assumption is that libraries used by
1606 -- the body are more likely to reference libraries used by the spec,
1610 (Linker_Options.Last,
1611 Move_Linker_Option'Access,
1612 Lt_Linker_Option'Access);
1614 -- Write user linker options, i.e. the set of linker options that
1615 -- come from all files other than GNAT internal files, Lgnat is
1616 -- left set to point to the first entry from a GNAT internal file,
1617 -- or past the end of the entriers if there are no internal files.
1619 Lgnat := Linker_Options.Last + 1;
1621 for J in 1 .. Linker_Options.Last loop
1622 if not Linker_Options.Table (J).Internal_File then
1623 Get_Name_String (Linker_Options.Table (J).Name);
1624 Write_Linker_Option;
1631 -- Now we insert standard linker options that must appear after the
1632 -- entries from user files, and before the entries from GNAT run-time
1633 -- files. The reason for this decision is that libraries referenced
1634 -- by internal routines may reference these standard library entries.
1636 if not (No_Run_Time_Specified or else Opt.No_Stdlib) then
1639 if Opt.Shared_Libgnat then
1640 Add_Str_To_Name_Buffer ("-shared");
1642 Add_Str_To_Name_Buffer ("-static");
1645 -- Write directly to avoid -K output (why???)
1647 Write_Info_Ada_C (" -- ", "", Name_Buffer (1 .. Name_Len));
1649 if With_DECGNAT then
1651 Add_Str_To_Name_Buffer ("-ldecgnat");
1652 Write_Linker_Option;
1657 Add_Str_To_Name_Buffer ("-lgnarl");
1658 Write_Linker_Option;
1662 Add_Str_To_Name_Buffer ("-lgnat");
1663 Write_Linker_Option;
1666 -- Write linker options from all internal files
1668 for J in Lgnat .. Linker_Options.Last loop
1669 Get_Name_String (Linker_Options.Table (J).Name);
1670 Write_Linker_Option;
1673 if Ada_Bind_File then
1674 WBI ("-- END Object file/option list ");
1676 WBI (" END Object file/option list */");
1679 end Gen_Object_Files_Options;
1681 ---------------------
1682 -- Gen_Output_File --
1683 ---------------------
1685 procedure Gen_Output_File (Filename : String) is
1686 Public_Version : constant Boolean := Gnat_Version_Type = "PUBLIC ";
1687 -- Set true if this is the public version of GNAT
1690 -- Override Ada_Bind_File and Bind_Main_Program for Java since
1691 -- JGNAT only supports Ada code, and the main program is already
1692 -- generated by the compiler.
1694 if Hostparm.Java_VM then
1695 Ada_Bind_File := True;
1696 Bind_Main_Program := False;
1699 -- Override time slice value if -T switch is set
1701 if Time_Slice_Set then
1702 ALIs.Table (ALIs.First).Time_Slice_Value := Opt.Time_Slice_Value;
1705 -- Count number of elaboration calls
1707 for E in Elab_Order.First .. Elab_Order.Last loop
1708 if Units.Table (Elab_Order.Table (E)).No_Elab then
1711 Num_Elab_Calls := Num_Elab_Calls + 1;
1715 -- Get the time stamp of the former bind for public version warning
1717 if Public_Version then
1718 Record_Time_From_Last_Bind;
1721 -- Generate output file in appropriate language
1723 if Ada_Bind_File then
1724 Gen_Output_File_Ada (Filename);
1726 Gen_Output_File_C (Filename);
1729 -- Periodically issue a warning when the public version is used on
1732 if Public_Version then
1733 Public_Version_Warning;
1735 end Gen_Output_File;
1737 -------------------------
1738 -- Gen_Output_File_Ada --
1739 -------------------------
1741 procedure Gen_Output_File_Ada (Filename : String) is
1744 -- Name of generated bind file (spec)
1747 -- Name of generated bind file (body)
1749 Ada_Main : constant String := Get_Ada_Main_Name;
1750 -- Name to be used for generated Ada main program. See the body of
1751 -- function Get_Ada_Main_Name for details on the form of the name.
1753 Target : constant String_Ptr := Target_Name;
1754 VxWorks_Target : constant Boolean :=
1755 Target (Target'Last - 7 .. Target'Last) = "vxworks/"
1756 or else Target (Target'Last - 9 .. Target'Last) = "vxworksae/";
1759 -- Create spec first
1761 Create_Binder_Output (Filename, 's', Bfiles);
1763 if No_Run_Time_Specified then
1764 WBI ("pragma No_Run_Time;");
1767 -- Generate with of System so we can reference System.Address, note
1768 -- that such a reference is safe even in No_Run_Time mode, since we
1769 -- do not need any run-time code for such a reference, and we output
1770 -- a pragma No_Run_Time for this compilation above.
1772 WBI ("with System;");
1774 -- Generate with of System.Initialize_Scalars if active
1776 if Initialize_Scalars_Used then
1777 WBI ("with System.Scalar_Values;");
1780 Resolve_Binder_Options;
1782 if not No_Run_Time_Specified then
1784 -- Usually, adafinal is called using a pragma Import C. Since
1785 -- Import C doesn't have the same semantics for JGNAT, we use
1788 if Hostparm.Java_VM then
1789 WBI ("with System.Standard_Library;");
1793 WBI ("package " & Ada_Main & " is");
1795 -- Main program case
1797 if Bind_Main_Program then
1799 -- Generate argc/argv stuff
1802 WBI (" gnat_argc : Integer;");
1803 WBI (" gnat_argv : System.Address;");
1804 WBI (" gnat_envp : System.Address;");
1806 -- If we have a run time present, these variables are in the
1807 -- runtime data area for easy access from the runtime
1809 if not No_Run_Time_Specified then
1811 WBI (" pragma Import (C, gnat_argc);");
1812 WBI (" pragma Import (C, gnat_argv);");
1813 WBI (" pragma Import (C, gnat_envp);");
1816 -- Define exit status. Again in normal mode, this is in the
1817 -- run-time library, and is initialized there, but in the no
1818 -- run time case, the variable is here and initialized here.
1822 if No_Run_Time_Specified then
1823 WBI (" gnat_exit_status : Integer := 0;");
1825 WBI (" gnat_exit_status : Integer;");
1826 WBI (" pragma Import (C, gnat_exit_status);");
1830 -- Generate the GNAT_Version and Ada_Main_Program_Name info only for
1831 -- the main program. Otherwise, it can lead under some circumstances
1832 -- to a symbol duplication during the link (for instance when a
1833 -- C program uses 2 Ada libraries)
1835 if Bind_Main_Program then
1837 WBI (" GNAT_Version : constant String :=");
1838 WBI (" ""GNAT Version: " &
1839 Gnat_Version_String & """;");
1840 WBI (" pragma Export (C, GNAT_Version, ""__gnat_version"");");
1843 Set_String (" Ada_Main_Program_Name : constant String := """);
1844 Get_Name_String (Units.Table (First_Unit_Entry).Uname);
1845 Set_Main_Program_Name;
1846 Set_String (""" & Ascii.NUL;");
1847 Write_Statement_Buffer;
1850 (" pragma Export (C, Ada_Main_Program_Name, " &
1851 """__gnat_ada_main_program_name"");");
1854 -- No need to generate a finalization routine if there is no
1855 -- runtime, since there is nothing to do in this case.
1857 if not No_Run_Time_Specified then
1859 WBI (" procedure " & Ada_Final_Name.all & ";");
1860 WBI (" pragma Export (C, " & Ada_Final_Name.all & ", """ &
1861 Ada_Final_Name.all & """);");
1865 WBI (" procedure " & Ada_Init_Name.all & ";");
1866 WBI (" pragma Export (C, " & Ada_Init_Name.all & ", """ &
1867 Ada_Init_Name.all & """);");
1869 if Bind_Main_Program then
1871 -- If we have a run time, then Break_Start is defined there, but
1872 -- if there is no run-time, Break_Start is defined in this file.
1875 WBI (" procedure Break_Start;");
1877 if No_Run_Time_Specified then
1878 WBI (" pragma Export (C, Break_Start, ""__gnat_break_start"");");
1880 WBI (" pragma Import (C, Break_Start, ""__gnat_break_start"");");
1884 WBI (" function " & Get_Main_Name);
1886 -- Generate argument list (except on VxWorks, where none is present)
1888 if not VxWorks_Target then
1889 WBI (" (argc : Integer;");
1890 WBI (" argv : System.Address;");
1891 WBI (" envp : System.Address)");
1894 WBI (" return Integer;");
1895 WBI (" pragma Export (C, " & Get_Main_Name & ", """ &
1896 Get_Main_Name & """);");
1899 if Initialize_Scalars_Used then
1909 WBI ("end " & Ada_Main & ";");
1910 Close_Binder_Output;
1912 -- Prepare to write body
1914 Create_Binder_Output (Filename, 'b', Bfileb);
1916 -- Output Source_File_Name pragmas which look like
1918 -- pragma Source_File_Name (Ada_Main, Spec_File_Name => "sss");
1919 -- pragma Source_File_Name (Ada_Main, Body_File_Name => "bbb");
1921 -- where sss/bbb are the spec/body file names respectively
1923 Get_Name_String (Bfiles);
1924 Name_Buffer (Name_Len + 1 .. Name_Len + 3) := """);";
1926 WBI ("pragma Source_File_Name (" &
1928 ", Spec_File_Name => """ &
1929 Name_Buffer (1 .. Name_Len + 3));
1931 Get_Name_String (Bfileb);
1932 Name_Buffer (Name_Len + 1 .. Name_Len + 3) := """);";
1934 WBI ("pragma Source_File_Name (" &
1936 ", Body_File_Name => """ &
1937 Name_Buffer (1 .. Name_Len + 3));
1940 WBI ("package body " & Ada_Main & " is");
1942 -- Import the finalization procedure only if there is a runtime.
1944 if not No_Run_Time_Specified then
1946 -- In the Java case, pragma Import C cannot be used, so the
1947 -- standard Ada constructs will be used instead.
1949 if not Hostparm.Java_VM then
1951 WBI (" procedure Do_Finalize;");
1953 (" pragma Import (C, Do_Finalize, " &
1954 """system__standard_library__adafinal"");");
1961 -- No need to generate a finalization routine if there is no
1962 -- runtime, since there is nothing to do in this case.
1964 if not No_Run_Time_Specified then
1968 if Bind_Main_Program then
1970 -- In No_Run_Time mode, generate dummy body for Break_Start
1972 if No_Run_Time_Specified then
1974 WBI (" procedure Break_Start is");
1983 -- Output object file list and the Ada body is complete
1985 Gen_Object_Files_Options;
1988 WBI ("end " & Ada_Main & ";");
1990 Close_Binder_Output;
1991 end Gen_Output_File_Ada;
1993 -----------------------
1994 -- Gen_Output_File_C --
1995 -----------------------
1997 procedure Gen_Output_File_C (Filename : String) is
2000 -- Name of generated bind file
2003 Create_Binder_Output (Filename, 'c', Bfile);
2005 Resolve_Binder_Options;
2007 WBI ("#ifdef __STDC__");
2008 WBI ("#define PARAMS(paramlist) paramlist");
2010 WBI ("#define PARAMS(paramlist) ()");
2014 WBI ("extern void __gnat_set_globals ");
2015 WBI (" PARAMS ((int, int, int, int, int, int, const char *,");
2016 WBI (" int, int, int));");
2017 WBI ("extern void " & Ada_Final_Name.all & " PARAMS ((void));");
2018 WBI ("extern void " & Ada_Init_Name.all & " PARAMS ((void));");
2020 WBI ("extern void system__standard_library__adafinal PARAMS ((void));");
2022 if not No_Main_Subprogram then
2023 WBI ("extern int main PARAMS ((int, char **, char **));");
2024 if Hostparm.OpenVMS then
2025 WBI ("extern void __posix_exit PARAMS ((int));");
2027 WBI ("extern void exit PARAMS ((int));");
2030 WBI ("extern void __gnat_break_start PARAMS ((void));");
2031 Set_String ("extern ");
2033 if ALIs.Table (ALIs.First).Main_Program = Proc then
2034 Set_String ("void ");
2036 Set_String ("int ");
2039 Get_Name_String (Units.Table (First_Unit_Entry).Uname);
2040 Set_Main_Program_Name;
2041 Set_String (" PARAMS ((void));");
2042 Write_Statement_Buffer;
2045 if not No_Run_Time_Specified then
2046 WBI ("extern void __gnat_initialize PARAMS ((void));");
2047 WBI ("extern void __gnat_finalize PARAMS ((void));");
2048 WBI ("extern void __gnat_install_handler PARAMS ((void));");
2055 -- Imported variable used to track elaboration/finalization phase.
2056 -- Used only when we have a runtime.
2058 if not No_Run_Time_Specified then
2059 WBI ("extern int __gnat_handler_installed;");
2063 -- Write argv/argc stuff if main program case
2065 if Bind_Main_Program then
2067 -- In the normal case, these are in the runtime library
2069 if not No_Run_Time_Specified then
2070 WBI ("extern int gnat_argc;");
2071 WBI ("extern char **gnat_argv;");
2072 WBI ("extern char **gnat_envp;");
2073 WBI ("extern int gnat_exit_status;");
2075 -- In the No_Run_Time case, they are right in the binder file
2076 -- and we initialize gnat_exit_status in the declaration.
2079 WBI ("int gnat_argc;");
2080 WBI ("char **gnat_argv;");
2081 WBI ("char **gnat_envp;");
2082 WBI ("int gnat_exit_status = 0;");
2088 -- In no run-time mode, the __gnat_break_start routine (for the
2089 -- debugger to get initial control) is defined in this file.
2091 if No_Run_Time_Specified then
2093 WBI ("void __gnat_break_start () {}");
2096 -- Generate the __gnat_version and __gnat_ada_main_program_name info
2097 -- only for the main program. Otherwise, it can lead under some
2098 -- circumstances to a symbol duplication during the link (for instance
2099 -- when a C program uses 2 Ada libraries)
2101 if Bind_Main_Program then
2103 WBI ("char __gnat_version[] = ""GNAT Version: " &
2104 Gnat_Version_String & """;");
2106 Set_String ("char __gnat_ada_main_program_name[] = """);
2107 Get_Name_String (Units.Table (First_Unit_Entry).Uname);
2108 Set_Main_Program_Name;
2110 Write_Statement_Buffer;
2113 -- Generate the adafinal routine. In no runtime mode, this is
2114 -- not needed, since there is no finalization to do.
2116 if not No_Run_Time_Specified then
2122 -- Main is only present for Ada main case
2124 if Bind_Main_Program then
2128 -- Scalar values, versions and object files needed in both cases
2130 if Initialize_Scalars_Used then
2136 Gen_Object_Files_Options;
2138 -- C binder output is complete
2140 Close_Binder_Output;
2141 end Gen_Output_File_C;
2143 -----------------------
2144 -- Gen_Scalar_Values --
2145 -----------------------
2147 procedure Gen_Scalar_Values is
2149 -- Strings to hold hex values of initialization constants. Note that
2150 -- we store these strings in big endian order, but they are actually
2151 -- used to initialize integer values, so the actual generated data
2152 -- will automaticaly have the right endianess.
2154 IS_Is1 : String (1 .. 2);
2155 IS_Is2 : String (1 .. 4);
2156 IS_Is4 : String (1 .. 8);
2157 IS_Is8 : String (1 .. 16);
2158 IS_Iu1 : String (1 .. 2);
2159 IS_Iu2 : String (1 .. 4);
2160 IS_Iu4 : String (1 .. 8);
2161 IS_Iu8 : String (1 .. 16);
2162 IS_Isf : String (1 .. 8);
2163 IS_Ifl : String (1 .. 8);
2164 IS_Ilf : String (1 .. 16);
2166 -- The string for Long_Long_Float is special. This is used only on the
2167 -- ia32 with 80-bit extended float (stored in 96 bits by gcc). The
2168 -- value here is represented little-endian, since that's the only way
2169 -- it is ever generated (this is not used on big-endian machines.
2171 IS_Ill : String (1 .. 24);
2174 -- -Sin (invalid values)
2176 if Opt.Initialize_Scalars_Mode = 'I' then
2179 IS_Is4 := "80000000";
2180 IS_Is8 := "8000000000000000";
2183 IS_Iu4 := "FFFFFFFF";
2184 IS_Iu8 := "FFFFFFFFFFFFFFFF";
2188 IS_Ill := "00000000000000C0FFFF0000";
2190 -- -Slo (low values)
2192 elsif Opt.Initialize_Scalars_Mode = 'L' then
2195 IS_Is4 := "80000000";
2196 IS_Is8 := "8000000000000000";
2199 IS_Iu4 := "00000000";
2200 IS_Iu8 := "0000000000000000";
2201 IS_Isf := "FF800000";
2203 IS_Ilf := "FFF0000000000000";
2204 IS_Ill := "0000000000000080FFFF0000";
2206 -- -Shi (high values)
2208 elsif Opt.Initialize_Scalars_Mode = 'H' then
2211 IS_Is4 := "7FFFFFFF";
2212 IS_Is8 := "7FFFFFFFFFFFFFFF";
2215 IS_Iu4 := "FFFFFFFF";
2216 IS_Iu8 := "FFFFFFFFFFFFFFFF";
2217 IS_Isf := "7F800000";
2219 IS_Ilf := "7FF0000000000000";
2220 IS_Ill := "0000000000000080FF7F0000";
2224 else pragma Assert (Opt.Initialize_Scalars_Mode = 'X');
2225 IS_Is1 (1 .. 2) := Opt.Initialize_Scalars_Val;
2226 IS_Is2 (1 .. 2) := Opt.Initialize_Scalars_Val;
2227 IS_Is2 (3 .. 4) := Opt.Initialize_Scalars_Val;
2229 for J in 1 .. 4 loop
2230 IS_Is4 (2 * J - 1 .. 2 * J) := Opt.Initialize_Scalars_Val;
2233 for J in 1 .. 8 loop
2234 IS_Is8 (2 * J - 1 .. 2 * J) := Opt.Initialize_Scalars_Val;
2246 for J in 1 .. 12 loop
2247 IS_Ill (2 * J - 1 .. 2 * J) := Opt.Initialize_Scalars_Val;
2251 -- Generate output, Ada case
2253 if Ada_Bind_File then
2256 Set_String (" IS_Is1 : constant System.Scalar_Values.Byte1 := 16#");
2257 Set_String (IS_Is1);
2258 Write_Statement_Buffer ("#;");
2260 Set_String (" IS_Is2 : constant System.Scalar_Values.Byte2 := 16#");
2261 Set_String (IS_Is2);
2262 Write_Statement_Buffer ("#;");
2264 Set_String (" IS_Is4 : constant System.Scalar_Values.Byte4 := 16#");
2265 Set_String (IS_Is4);
2266 Write_Statement_Buffer ("#;");
2268 Set_String (" IS_Is8 : constant System.Scalar_Values.Byte8 := 16#");
2269 Set_String (IS_Is8);
2270 Write_Statement_Buffer ("#;");
2272 Set_String (" IS_Iu1 : constant System.Scalar_Values.Byte1 := 16#");
2273 Set_String (IS_Iu1);
2274 Write_Statement_Buffer ("#;");
2276 Set_String (" IS_Iu2 : constant System.Scalar_Values.Byte2 := 16#");
2277 Set_String (IS_Iu2);
2278 Write_Statement_Buffer ("#;");
2280 Set_String (" IS_Iu4 : constant System.Scalar_Values.Byte4 := 16#");
2281 Set_String (IS_Iu4);
2282 Write_Statement_Buffer ("#;");
2284 Set_String (" IS_Iu8 : constant System.Scalar_Values.Byte8 := 16#");
2285 Set_String (IS_Iu8);
2286 Write_Statement_Buffer ("#;");
2288 Set_String (" IS_Isf : constant System.Scalar_Values.Byte4 := 16#");
2289 Set_String (IS_Isf);
2290 Write_Statement_Buffer ("#;");
2292 Set_String (" IS_Ifl : constant System.Scalar_Values.Byte4 := 16#");
2293 Set_String (IS_Ifl);
2294 Write_Statement_Buffer ("#;");
2296 Set_String (" IS_Ilf : constant System.Scalar_Values.Byte8 := 16#");
2297 Set_String (IS_Ilf);
2298 Write_Statement_Buffer ("#;");
2300 -- Special case of Long_Long_Float. This is a 10-byte value used
2301 -- only on the x86. We could omit it for other architectures, but
2302 -- we don't easily have that kind of target specialization in the
2303 -- binder, and it's only 10 bytes, and only if -Sxx is used. Note
2304 -- that for architectures where Long_Long_Float is the same as
2305 -- Long_Float, the expander uses the Long_Float constant for the
2306 -- initializations of Long_Long_Float values.
2308 WBI (" IS_Ill : constant array (1 .. 12) of");
2309 WBI (" System.Scalar_Values.Byte1 := (");
2312 for J in 1 .. 6 loop
2313 Set_String (" 16#");
2314 Set_Char (IS_Ill (2 * J - 1));
2315 Set_Char (IS_Ill (2 * J));
2319 Write_Statement_Buffer;
2322 for J in 7 .. 12 loop
2323 Set_String (" 16#");
2324 Set_Char (IS_Ill (2 * J - 1));
2325 Set_Char (IS_Ill (2 * J));
2334 Write_Statement_Buffer;
2336 -- Output export statements to export to System.Scalar_Values
2340 WBI (" pragma Export (Ada, IS_Is1, ""__gnat_Is1"");");
2341 WBI (" pragma Export (Ada, IS_Is2, ""__gnat_Is2"");");
2342 WBI (" pragma Export (Ada, IS_Is4, ""__gnat_Is4"");");
2343 WBI (" pragma Export (Ada, IS_Is8, ""__gnat_Is8"");");
2344 WBI (" pragma Export (Ada, IS_Iu1, ""__gnat_Iu1"");");
2345 WBI (" pragma Export (Ada, IS_Iu2, ""__gnat_Iu2"");");
2346 WBI (" pragma Export (Ada, IS_Iu4, ""__gnat_Iu4"");");
2347 WBI (" pragma Export (Ada, IS_Iu8, ""__gnat_Iu8"");");
2348 WBI (" pragma Export (Ada, IS_Isf, ""__gnat_Isf"");");
2349 WBI (" pragma Export (Ada, IS_Ifl, ""__gnat_Ifl"");");
2350 WBI (" pragma Export (Ada, IS_Ilf, ""__gnat_Ilf"");");
2351 WBI (" pragma Export (Ada, IS_Ill, ""__gnat_Ill"");");
2353 -- Generate output C case
2356 -- The lines we generate in this case are of the form
2357 -- typ __gnat_I?? = 0x??;
2358 -- where typ is appropriate to the length
2362 Set_String ("unsigned char __gnat_Is1 = 0x");
2363 Set_String (IS_Is1);
2364 Write_Statement_Buffer (";");
2366 Set_String ("unsigned short __gnat_Is2 = 0x");
2367 Set_String (IS_Is2);
2368 Write_Statement_Buffer (";");
2370 Set_String ("unsigned __gnat_Is4 = 0x");
2371 Set_String (IS_Is4);
2372 Write_Statement_Buffer (";");
2374 Set_String ("long long unsigned __gnat_Is8 = 0x");
2375 Set_String (IS_Is8);
2376 Write_Statement_Buffer ("LL;");
2378 Set_String ("unsigned char __gnat_Iu1 = 0x");
2379 Set_String (IS_Is1);
2380 Write_Statement_Buffer (";");
2382 Set_String ("unsigned short __gnat_Iu2 = 0x");
2383 Set_String (IS_Is2);
2384 Write_Statement_Buffer (";");
2386 Set_String ("unsigned __gnat_Iu4 = 0x");
2387 Set_String (IS_Is4);
2388 Write_Statement_Buffer (";");
2390 Set_String ("long long unsigned __gnat_Iu8 = 0x");
2391 Set_String (IS_Is8);
2392 Write_Statement_Buffer ("LL;");
2394 Set_String ("unsigned __gnat_Isf = 0x");
2395 Set_String (IS_Isf);
2396 Write_Statement_Buffer (";");
2398 Set_String ("unsigned __gnat_Ifl = 0x");
2399 Set_String (IS_Ifl);
2400 Write_Statement_Buffer (";");
2402 Set_String ("long long unsigned __gnat_Ilf = 0x");
2403 Set_String (IS_Ilf);
2404 Write_Statement_Buffer ("LL;");
2406 -- For Long_Long_Float, we generate
2407 -- char __gnat_Ill[12] = {0x??, 0x??, 0x??, 0x??, 0x??, 0x??,
2408 -- 0x??, 0x??, 0x??, 0x??, 0x??, 0x??);
2410 Set_String ("unsigned char __gnat_Ill[12] = {");
2412 for J in 1 .. 6 loop
2414 Set_Char (IS_Ill (2 * J - 1));
2415 Set_Char (IS_Ill (2 * J));
2419 Write_Statement_Buffer;
2422 for J in 7 .. 12 loop
2424 Set_Char (IS_Ill (2 * J - 1));
2425 Set_Char (IS_Ill (2 * J));
2434 Write_Statement_Buffer;
2436 end Gen_Scalar_Values;
2438 ----------------------
2439 -- Gen_Versions_Ada --
2440 ----------------------
2442 -- This routine generates two sets of lines. The first set has the form:
2444 -- unnnnn : constant Integer := 16#hhhhhhhh#;
2446 -- The second set has the form
2448 -- pragma Export (C, unnnnn, unam);
2450 -- for each unit, where unam is the unit name suffixed by either B or
2451 -- S for body or spec, with dots replaced by double underscores, and
2452 -- hhhhhhhh is the version number, and nnnnn is a 5-digits serial number.
2454 procedure Gen_Versions_Ada is
2455 Ubuf : String (1 .. 6) := "u00000";
2457 procedure Increment_Ubuf;
2458 -- Little procedure to increment the serial number
2460 procedure Increment_Ubuf is
2462 for J in reverse Ubuf'Range loop
2463 Ubuf (J) := Character'Succ (Ubuf (J));
2464 exit when Ubuf (J) <= '9';
2469 -- Start of processing for Gen_Versions_Ada
2472 if Bind_For_Library then
2474 -- When building libraries, the version number of each unit can
2475 -- not be computed, since the binder does not know the full list
2476 -- of units. Therefore, the 'Version and 'Body_Version
2477 -- attributes can not supported in this case.
2484 WBI (" type Version_32 is mod 2 ** 32;");
2485 for U in Units.First .. Units.Last loop
2487 WBI (" " & Ubuf & " : constant Version_32 := 16#" &
2488 Units.Table (U).Version & "#;");
2494 for U in Units.First .. Units.Last loop
2496 Set_String (" pragma Export (C, ");
2498 Set_String (", """);
2500 Get_Name_String (Units.Table (U).Uname);
2502 for K in 1 .. Name_Len loop
2503 if Name_Buffer (K) = '.' then
2507 elsif Name_Buffer (K) = '%' then
2511 Set_Char (Name_Buffer (K));
2515 if Name_Buffer (Name_Len) = 's' then
2521 Set_String (""");");
2522 Write_Statement_Buffer;
2525 end Gen_Versions_Ada;
2527 --------------------
2528 -- Gen_Versions_C --
2529 --------------------
2531 -- This routine generates a line of the form:
2533 -- unsigned unam = 0xhhhhhhhh;
2535 -- for each unit, where unam is the unit name suffixed by either B or
2536 -- S for body or spec, with dots replaced by double underscores.
2538 procedure Gen_Versions_C is
2540 if Bind_For_Library then
2542 -- When building libraries, the version number of each unit can
2543 -- not be computed, since the binder does not know the full list
2544 -- of units. Therefore, the 'Version and 'Body_Version
2545 -- attributes can not supported.
2550 for U in Units.First .. Units.Last loop
2551 Set_String ("unsigned ");
2553 Get_Name_String (Units.Table (U).Uname);
2555 for K in 1 .. Name_Len loop
2556 if Name_Buffer (K) = '.' then
2559 elsif Name_Buffer (K) = '%' then
2563 Set_Char (Name_Buffer (K));
2567 if Name_Buffer (Name_Len) = 's' then
2573 Set_String (" = 0x");
2574 Set_String (Units.Table (U).Version);
2576 Write_Statement_Buffer;
2581 -----------------------
2582 -- Get_Ada_Main_Name --
2583 -----------------------
2585 function Get_Ada_Main_Name return String is
2586 Suffix : constant String := "_00";
2587 Name : String (1 .. Opt.Ada_Main_Name.all'Length + Suffix'Length) :=
2588 Opt.Ada_Main_Name.all & Suffix;
2592 -- The main program generated by JGNAT expects a package called
2593 -- ada_<main procedure>.
2595 if Hostparm.Java_VM then
2596 -- Get main program name
2598 Get_Name_String (Units.Table (First_Unit_Entry).Uname);
2602 return "ada_" & Name_Buffer (1 .. Name_Len - 2);
2605 -- This loop tries the following possibilities in order
2611 -- where <Ada_Main> is equal to Opt.Ada_Main_Name. By default,
2612 -- it is set to 'ada_main'.
2614 for J in 0 .. 99 loop
2616 Nlen := Name'Length - Suffix'Length;
2618 Nlen := Name'Length;
2619 Name (Name'Last) := Character'Val (J mod 10 + Character'Pos ('0'));
2620 Name (Name'Last - 1) :=
2621 Character'Val (J / 10 + Character'Pos ('0'));
2624 for K in ALIs.First .. ALIs.Last loop
2625 for L in ALIs.Table (K).First_Unit .. ALIs.Table (K).Last_Unit loop
2627 -- Get unit name, removing %b or %e at end
2629 Get_Name_String (Units.Table (L).Uname);
2630 Name_Len := Name_Len - 2;
2632 if Name_Buffer (1 .. Name_Len) = Name (1 .. Nlen) then
2638 return Name (1 .. Nlen);
2644 -- If we fall through, just use a peculiar unlikely name
2646 return ("Qwertyuiop");
2647 end Get_Ada_Main_Name;
2653 function Get_Main_Name return String is
2654 Target : constant String_Ptr := Target_Name;
2655 VxWorks_Target : constant Boolean :=
2656 Target (Target'Last - 7 .. Target'Last) = "vxworks/"
2657 or else Target (Target'Last - 9 .. Target'Last) = "vxworksae/";
2660 -- Explicit name given with -M switch
2662 if Bind_Alternate_Main_Name then
2663 return Alternate_Main_Name.all;
2665 -- Case of main program name to be used directly
2667 elsif VxWorks_Target then
2669 -- Get main program name
2671 Get_Name_String (Units.Table (First_Unit_Entry).Uname);
2673 -- If this is a child name, return only the name of the child,
2674 -- since we can't have dots in a nested program name. Note that
2675 -- we do not include the %b at the end of the unit name.
2677 for J in reverse 1 .. Name_Len - 2 loop
2678 if J = 1 or else Name_Buffer (J - 1) = '.' then
2679 return Name_Buffer (J .. Name_Len - 2);
2683 raise Program_Error; -- impossible exit
2685 -- Case where "main" is to be used as default
2692 ----------------------
2693 -- Lt_Linker_Option --
2694 ----------------------
2696 function Lt_Linker_Option (Op1, Op2 : Natural) return Boolean is
2698 -- Sort internal files last
2700 if Linker_Options.Table (Op1).Internal_File
2702 Linker_Options.Table (Op2).Internal_File
2704 -- Note: following test uses False < True
2706 return Linker_Options.Table (Op1).Internal_File
2708 Linker_Options.Table (Op2).Internal_File;
2710 -- If both internal or both non-internal, sort according to the
2711 -- elaboration position. A unit that is elaborated later should
2712 -- come earlier in the linker options list.
2715 return Units.Table (Linker_Options.Table (Op1).Unit).Elab_Position
2717 Units.Table (Linker_Options.Table (Op2).Unit).Elab_Position;
2720 end Lt_Linker_Option;
2722 ------------------------
2723 -- Move_Linker_Option --
2724 ------------------------
2726 procedure Move_Linker_Option (From : Natural; To : Natural) is
2728 Linker_Options.Table (To) := Linker_Options.Table (From);
2729 end Move_Linker_Option;
2731 ----------------------------
2732 -- Public_Version_Warning --
2733 ----------------------------
2735 procedure Public_Version_Warning is
2737 Time : Int := Time_From_Last_Bind;
2739 -- Constants to help defining periods
2741 Hour : constant := 60;
2742 Day : constant := 24 * Hour;
2744 Never : constant := Integer'Last;
2745 -- Special value indicating no warnings should be given
2747 -- Constants defining when the warning is issued. Programs with more
2748 -- than Large Units will issue a warning every Period_Large amount of
2749 -- time. Smaller programs will generate a warning every Period_Small
2752 Large : constant := 20;
2753 -- Threshold for considering a program small or large
2755 Period_Large : constant := Day;
2756 -- Periodic warning time for large programs
2758 Period_Small : constant := Never;
2759 -- Periodic warning time for small programs
2764 -- Compute the number of units that are not GNAT internal files
2767 for A in ALIs.First .. ALIs.Last loop
2768 if not Is_Internal_File_Name (ALIs.Table (A).Sfile) then
2769 Nb_Unit := Nb_Unit + 1;
2773 -- Do not emit the message if the last message was emitted in the
2774 -- specified period taking into account the number of units.
2776 if Nb_Unit < Large and then Time <= Period_Small then
2779 elsif Time <= Period_Large then
2784 Write_Str ("IMPORTANT NOTICE:");
2786 Write_Str (" This version of GNAT is unsupported"
2787 & " and comes with absolutely no warranty.");
2789 Write_Str (" If you intend to evaluate or use GNAT for building "
2790 & "commercial applications,");
2792 Write_Str (" please consult http://www.gnat.com/ for information");
2794 Write_Str (" on the GNAT Professional product line.");
2797 end Public_Version_Warning;
2799 ----------------------------
2800 -- Resolve_Binder_Options --
2801 ----------------------------
2803 procedure Resolve_Binder_Options is
2805 for E in Elab_Order.First .. Elab_Order.Last loop
2806 Get_Name_String (Units.Table (Elab_Order.Table (E)).Uname);
2808 -- The procedure of looking for specific packages and setting
2809 -- flags is very wrong, but there isn't a good alternative at
2812 if Name_Buffer (1 .. 19) = "system.os_interface" then
2816 if Hostparm.OpenVMS and then Name_Buffer (1 .. 3) = "dec" then
2817 With_DECGNAT := True;
2820 end Resolve_Binder_Options;
2826 procedure Set_Char (C : Character) is
2829 Statement_Buffer (Last) := C;
2836 procedure Set_Int (N : Int) is
2848 Statement_Buffer (Last) :=
2849 Character'Val (N mod 10 + Character'Pos ('0'));
2853 ---------------------------
2854 -- Set_Main_Program_Name --
2855 ---------------------------
2857 procedure Set_Main_Program_Name is
2859 -- Note that name has %b on the end which we ignore
2861 -- First we output the initial _ada_ since we know that the main
2862 -- program is a library level subprogram.
2864 Set_String ("_ada_");
2866 -- Copy name, changing dots to double underscores
2868 for J in 1 .. Name_Len - 2 loop
2869 if Name_Buffer (J) = '.' then
2872 Set_Char (Name_Buffer (J));
2875 end Set_Main_Program_Name;
2877 ---------------------
2878 -- Set_Name_Buffer --
2879 ---------------------
2881 procedure Set_Name_Buffer is
2883 for J in 1 .. Name_Len loop
2884 Set_Char (Name_Buffer (J));
2886 end Set_Name_Buffer;
2892 procedure Set_String (S : String) is
2894 Statement_Buffer (Last + 1 .. Last + S'Length) := S;
2895 Last := Last + S'Length;
2902 procedure Set_Unit_Name is
2904 for J in 1 .. Name_Len - 2 loop
2905 if Name_Buffer (J) /= '.' then
2906 Set_Char (Name_Buffer (J));
2913 ---------------------
2914 -- Set_Unit_Number --
2915 ---------------------
2917 procedure Set_Unit_Number (U : Unit_Id) is
2918 Num_Units : constant Nat := Nat (Units.Table'Last) - Nat (Unit_Id'First);
2919 Unum : constant Nat := Nat (U) - Nat (Unit_Id'First);
2922 if Num_Units >= 10 and then Unum < 10 then
2926 if Num_Units >= 100 and then Unum < 100 then
2931 end Set_Unit_Number;
2937 procedure Tab_To (N : Natural) is
2944 ----------------------
2945 -- Write_Info_Ada_C --
2946 ----------------------
2948 procedure Write_Info_Ada_C (Ada : String; C : String; Common : String) is
2950 if Ada_Bind_File then
2952 S : String (1 .. Ada'Length + Common'Length);
2955 S (1 .. Ada'Length) := Ada;
2956 S (Ada'Length + 1 .. S'Length) := Common;
2962 S : String (1 .. C'Length + Common'Length);
2965 S (1 .. C'Length) := C;
2966 S (C'Length + 1 .. S'Length) := Common;
2970 end Write_Info_Ada_C;
2972 ----------------------------
2973 -- Write_Statement_Buffer --
2974 ----------------------------
2976 procedure Write_Statement_Buffer is
2978 WBI (Statement_Buffer (1 .. Last));
2980 end Write_Statement_Buffer;
2982 procedure Write_Statement_Buffer (S : String) is
2985 Write_Statement_Buffer;
2986 end Write_Statement_Buffer;