diff options
Diffstat (limited to 'gcc-4.2.1/gcc/ada/lib-load.adb')
-rw-r--r-- | gcc-4.2.1/gcc/ada/lib-load.adb | 775 |
1 files changed, 0 insertions, 775 deletions
diff --git a/gcc-4.2.1/gcc/ada/lib-load.adb b/gcc-4.2.1/gcc/ada/lib-load.adb deleted file mode 100644 index 248c5fcf9..000000000 --- a/gcc-4.2.1/gcc/ada/lib-load.adb +++ /dev/null @@ -1,775 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- L I B . L O A D -- --- -- --- B o d y -- --- -- --- Copyright (C) 1992-2005, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 2, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- --- for more details. You should have received a copy of the GNU General -- --- Public License distributed with GNAT; see file COPYING. If not, write -- --- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, -- --- Boston, MA 02110-1301, USA. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - -with Atree; use Atree; -with Debug; use Debug; -with Einfo; use Einfo; -with Errout; use Errout; -with Fname; use Fname; -with Fname.UF; use Fname.UF; -with Namet; use Namet; -with Nlists; use Nlists; -with Nmake; use Nmake; -with Opt; use Opt; -with Osint; use Osint; -with Osint.C; use Osint.C; -with Output; use Output; -with Par; -with Restrict; use Restrict; -with Scn; use Scn; -with Sinfo; use Sinfo; -with Sinput; use Sinput; -with Sinput.L; use Sinput.L; -with Stand; use Stand; -with Tbuild; use Tbuild; -with Uname; use Uname; - -package body Lib.Load is - - ----------------------- - -- Local Subprograms -- - ----------------------- - - function From_Limited_With_Chain (Lim : Boolean) return Boolean; - -- Check whether a possible circular dependence includes units that - -- have been loaded through limited_with clauses, in which case there - -- is no real circularity. - - function Spec_Is_Irrelevant - (Spec_Unit : Unit_Number_Type; - Body_Unit : Unit_Number_Type) return Boolean; - -- The Spec_Unit and Body_Unit parameters are the unit numbers of the - -- spec file that corresponds to the main unit which is a body. This - -- function determines if the spec file is irrelevant and will be - -- overridden by the body as described in RM 10.1.4(4). See description - -- in "Special Handling of Subprogram Bodies" for further details. - - procedure Write_Dependency_Chain; - -- This procedure is used to generate error message info lines that - -- trace the current dependency chain when a load error occurs. - - ------------------------------- - -- Create_Dummy_Package_Unit -- - ------------------------------- - - function Create_Dummy_Package_Unit - (With_Node : Node_Id; - Spec_Name : Unit_Name_Type) return Unit_Number_Type - is - Unum : Unit_Number_Type; - Cunit_Entity : Entity_Id; - Cunit : Node_Id; - Du_Name : Node_Or_Entity_Id; - End_Lab : Node_Id; - Save_CS : constant Boolean := Get_Comes_From_Source_Default; - - begin - -- The created dummy package unit does not come from source - - Set_Comes_From_Source_Default (False); - - -- Normal package - - if Nkind (Name (With_Node)) = N_Identifier then - Cunit_Entity := - Make_Defining_Identifier (No_Location, - Chars => Chars (Name (With_Node))); - Du_Name := Cunit_Entity; - End_Lab := New_Occurrence_Of (Cunit_Entity, No_Location); - - -- Child package - - else - Cunit_Entity := - Make_Defining_Identifier (No_Location, - Chars => Chars (Selector_Name (Name (With_Node)))); - Du_Name := - Make_Defining_Program_Unit_Name (No_Location, - Name => New_Copy_Tree (Prefix (Name (With_Node))), - Defining_Identifier => Cunit_Entity); - - Set_Is_Child_Unit (Cunit_Entity); - - End_Lab := - Make_Designator (No_Location, - Name => New_Copy_Tree (Prefix (Name (With_Node))), - Identifier => New_Occurrence_Of (Cunit_Entity, No_Location)); - end if; - - Set_Scope (Cunit_Entity, Standard_Standard); - - Cunit := - Make_Compilation_Unit (No_Location, - Context_Items => Empty_List, - Unit => - Make_Package_Declaration (No_Location, - Specification => - Make_Package_Specification (No_Location, - Defining_Unit_Name => Du_Name, - Visible_Declarations => Empty_List, - End_Label => End_Lab)), - Aux_Decls_Node => - Make_Compilation_Unit_Aux (No_Location)); - - -- Mark the dummy package as analyzed to prevent analysis of this - -- (non-existent) unit in -gnatQ mode because at the moment the - -- structure and attributes of this dummy package does not allow - -- a normal analysis of this unit - - Set_Analyzed (Cunit); - - Units.Increment_Last; - Unum := Units.Last; - - Units.Table (Unum) := ( - Cunit => Cunit, - Cunit_Entity => Cunit_Entity, - Dependency_Num => 0, - Dynamic_Elab => False, - Error_Location => Sloc (With_Node), - Expected_Unit => Spec_Name, - Fatal_Error => True, - Generate_Code => False, - Has_RACW => False, - Ident_String => Empty, - Loading => False, - Main_Priority => Default_Main_Priority, - Munit_Index => 0, - Serial_Number => 0, - Source_Index => No_Source_File, - Unit_File_Name => Get_File_Name (Spec_Name, Subunit => False), - Unit_Name => Spec_Name, - Version => 0); - - Set_Comes_From_Source_Default (Save_CS); - Set_Error_Posted (Cunit_Entity); - Set_Error_Posted (Cunit); - return Unum; - end Create_Dummy_Package_Unit; - - ----------------------------- - -- From_Limited_With_Chain -- - ----------------------------- - - function From_Limited_With_Chain (Lim : Boolean) return Boolean is - begin - -- True if the current load operation is through a limited_with clause - - if Lim then - return True; - - -- Examine the Load_Stack to locate any previous Limited_with clause - - elsif Load_Stack.Last - 1 > Load_Stack.First then - for U in Load_Stack.First .. Load_Stack.Last - 1 loop - if Load_Stack.Table (U).From_Limited_With then - return True; - end if; - end loop; - end if; - - return False; - end From_Limited_With_Chain; - - ---------------- - -- Initialize -- - ---------------- - - procedure Initialize is - begin - Units.Init; - Load_Stack.Init; - end Initialize; - - ------------------------ - -- Initialize_Version -- - ------------------------ - - procedure Initialize_Version (U : Unit_Number_Type) is - begin - Units.Table (U).Version := Source_Checksum (Source_Index (U)); - end Initialize_Version; - - ---------------------- - -- Load_Main_Source -- - ---------------------- - - procedure Load_Main_Source is - Fname : File_Name_Type; - - begin - Load_Stack.Increment_Last; - Load_Stack.Table (Load_Stack.Last) := (Main_Unit, False); - - -- Initialize unit table entry for Main_Unit. Note that we don't know - -- the unit name yet, that gets filled in when the parser parses the - -- main unit, at which time a check is made that it matches the main - -- file name, and then the Unit_Name field is set. The Cunit and - -- Cunit_Entity fields also get filled in later by the parser. - - Units.Increment_Last; - Fname := Next_Main_Source; - - Units.Table (Main_Unit).Unit_File_Name := Fname; - - if Fname /= No_File then - Main_Source_File := Load_Source_File (Fname); - Current_Error_Source_File := Main_Source_File; - - Units.Table (Main_Unit) := ( - Cunit => Empty, - Cunit_Entity => Empty, - Dependency_Num => 0, - Dynamic_Elab => False, - Error_Location => No_Location, - Expected_Unit => No_Name, - Fatal_Error => False, - Generate_Code => False, - Has_RACW => False, - Ident_String => Empty, - Loading => True, - Main_Priority => Default_Main_Priority, - Munit_Index => 0, - Serial_Number => 0, - Source_Index => Main_Source_File, - Unit_File_Name => Fname, - Unit_Name => No_Name, - Version => Source_Checksum (Main_Source_File)); - end if; - end Load_Main_Source; - - --------------- - -- Load_Unit -- - --------------- - - function Load_Unit - (Load_Name : Unit_Name_Type; - Required : Boolean; - Error_Node : Node_Id; - Subunit : Boolean; - Corr_Body : Unit_Number_Type := No_Unit; - Renamings : Boolean := False; - From_Limited_With : Boolean := False) return Unit_Number_Type - is - Calling_Unit : Unit_Number_Type; - Uname_Actual : Unit_Name_Type; - Unum : Unit_Number_Type; - Unump : Unit_Number_Type; - Fname : File_Name_Type; - Src_Ind : Source_File_Index; - - -- Start of processing for Load_Unit - - begin - -- If renamings are allowed and we have a child unit name, then we - -- must first load the parent to deal with finding the real name. - - if Renamings and then Is_Child_Name (Load_Name) then - Unump := - Load_Unit - (Load_Name => Get_Parent_Spec_Name (Load_Name), - Required => Required, - Subunit => False, - Renamings => True, - Error_Node => Error_Node); - - if Unump = No_Unit then - return No_Unit; - end if; - - -- If parent is a renaming, then we use the renamed package as - -- the actual parent for the subsequent load operation. - - if Nkind (Parent (Cunit_Entity (Unump))) = - N_Package_Renaming_Declaration - then - Uname_Actual := - New_Child - (Load_Name, - Get_Unit_Name (Name (Parent (Cunit_Entity (Unump))))); - - -- Save the renaming entity, to establish its visibility when - -- installing the context. The implicit with is on this entity, - -- not on the package it renames. - - if Nkind (Error_Node) = N_With_Clause - and then Nkind (Name (Error_Node)) = N_Selected_Component - then - declare - Par : Node_Id := Name (Error_Node); - - begin - while Nkind (Par) = N_Selected_Component - and then Chars (Selector_Name (Par)) /= - Chars (Cunit_Entity (Unump)) - loop - Par := Prefix (Par); - end loop; - - -- Case of some intermediate parent is a renaming - - if Nkind (Par) = N_Selected_Component then - Set_Entity (Selector_Name (Par), Cunit_Entity (Unump)); - - -- Case where the ultimate parent is a renaming - - else - Set_Entity (Par, Cunit_Entity (Unump)); - end if; - end; - end if; - - -- If the parent is not a renaming, then get its name (this may - -- be different from the parent spec name obtained above because - -- of renamings higher up in the hierarchy). - - else - Uname_Actual := New_Child (Load_Name, Unit_Name (Unump)); - end if; - - -- Here if unit to be loaded is not a child unit - - else - Uname_Actual := Load_Name; - end if; - - Fname := Get_File_Name (Uname_Actual, Subunit); - - if Debug_Flag_L then - Write_Eol; - Write_Str ("*** Load request for unit: "); - Write_Unit_Name (Load_Name); - - if Required then - Write_Str (" (Required = True)"); - else - Write_Str (" (Required = False)"); - end if; - - Write_Eol; - - if Uname_Actual /= Load_Name then - Write_Str ("*** Actual unit loaded: "); - Write_Unit_Name (Uname_Actual); - end if; - end if; - - -- Capture error location if it is for the main unit. The idea is to - -- post errors on the main unit location, not the most recent unit. - -- Note: Unit_Name (Main_Unit) is not set if we are parsing gnat.adc. - - if Present (Error_Node) - and then Unit_Name (Main_Unit) /= No_Name - then - -- It seems like In_Extended_Main_Source_Unit (Error_Node) would - -- do the trick here, but that's wrong, it is much too early to - -- call this routine. We are still in the parser, and the required - -- semantic information is not established yet. So we base the - -- judgment on unit names. - - Get_External_Unit_Name_String (Unit_Name (Main_Unit)); - - declare - Main_Unit_Name : constant String := Name_Buffer (1 .. Name_Len); - - begin - Get_External_Unit_Name_String - (Unit_Name (Get_Source_Unit (Error_Node))); - - -- If the two names are identical, then for sure we are part - -- of the extended main unit - - if Main_Unit_Name = Name_Buffer (1 .. Name_Len) then - Load_Msg_Sloc := Sloc (Error_Node); - - -- If the load is called from a with_type clause, the error - -- node is correct. - - elsif Nkind (Parent (Error_Node)) = N_With_Type_Clause then - Load_Msg_Sloc := Sloc (Error_Node); - - -- Otherwise, check for the subunit case, and if so, consider - -- we have a match if one name is a prefix of the other name. - - else - if Nkind (Unit (Cunit (Main_Unit))) = N_Subunit - or else - Nkind (Unit (Cunit (Get_Source_Unit (Error_Node)))) = - N_Subunit - then - Name_Len := Integer'Min (Name_Len, Main_Unit_Name'Length); - - if Name_Buffer (1 .. Name_Len) - = - Main_Unit_Name (1 .. Name_Len) - then - Load_Msg_Sloc := Sloc (Error_Node); - end if; - end if; - end if; - end; - end if; - - -- If we are generating error messages, then capture calling unit - - if Present (Error_Node) then - Calling_Unit := Get_Source_Unit (Error_Node); - else - Calling_Unit := No_Unit; - end if; - - -- See if we already have an entry for this unit - - Unum := Main_Unit; - - while Unum <= Units.Last loop - exit when Uname_Actual = Units.Table (Unum).Unit_Name; - Unum := Unum + 1; - end loop; - - -- Whether or not the entry was found, Unum is now the right value, - -- since it is one more than Units.Last (i.e. the index of the new - -- entry we will create) in the not found case. - - -- A special check is necessary in the unit not found case. If the unit - -- is not found, but the file in which it lives has already been loaded, - -- then we have the problem that the file does not contain the unit that - -- is needed. We simply treat this as a file not found condition. - - -- We skip this test in multiple unit per file mode since in this - -- case we can have multiple units from the same source file. - - if Unum > Units.Last and then Multiple_Unit_Index = 0 then - for J in Units.First .. Units.Last loop - if Fname = Units.Table (J).Unit_File_Name then - if Debug_Flag_L then - Write_Str (" file does not contain unit, Unit_Number = "); - Write_Int (Int (Unum)); - Write_Eol; - Write_Eol; - end if; - - if Present (Error_Node) then - if Is_Predefined_File_Name (Fname) then - Error_Msg_Name_1 := Uname_Actual; - Error_Msg - ("% is not a language defined unit", Load_Msg_Sloc); - else - Error_Msg_Name_1 := Fname; - Error_Msg_Unit_1 := Uname_Actual; - Error_Msg - ("File{ does not contain unit$", Load_Msg_Sloc); - end if; - - Write_Dependency_Chain; - return No_Unit; - - else - return No_Unit; - end if; - end if; - end loop; - end if; - - -- If we are proceeding with load, then make load stack entry, - -- and indicate the kind of with_clause responsible for the load. - - Load_Stack.Increment_Last; - Load_Stack.Table (Load_Stack.Last) := (Unum, From_Limited_With); - - -- Case of entry already in table - - if Unum <= Units.Last then - - -- Here is where we check for a circular dependency, which is - -- an attempt to load a unit which is currently in the process - -- of being loaded. We do *not* care about a circular chain that - -- leads back to a body, because this kind of circular dependence - -- legitimately occurs (e.g. two package bodies that contain - -- inlined subprogram referenced by the other). - - -- Ada 2005 (AI-50217): We also ignore limited_with clauses, because - -- their purpose is precisely to create legal circular structures. - - if Loading (Unum) - and then (Is_Spec_Name (Units.Table (Unum).Unit_Name) - or else Acts_As_Spec (Units.Table (Unum).Cunit)) - and then (Nkind (Error_Node) /= N_With_Clause - or else not Limited_Present (Error_Node)) - and then not From_Limited_With_Chain (From_Limited_With) - then - if Debug_Flag_L then - Write_Str (" circular dependency encountered"); - Write_Eol; - end if; - - if Present (Error_Node) then - Error_Msg ("circular unit dependency", Load_Msg_Sloc); - Write_Dependency_Chain; - else - Load_Stack.Decrement_Last; - end if; - - return No_Unit; - end if; - - if Debug_Flag_L then - Write_Str (" unit already in file table, Unit_Number = "); - Write_Int (Int (Unum)); - Write_Eol; - end if; - - Load_Stack.Decrement_Last; - return Unum; - - -- Unit is not already in table, so try to open the file - - else - if Debug_Flag_L then - Write_Str (" attempt unit load, Unit_Number = "); - Write_Int (Int (Unum)); - Write_Eol; - end if; - - Src_Ind := Load_Source_File (Fname); - - -- Make a partial entry in the file table, used even in the file not - -- found case to print the dependency chain including the last entry - - Units.Increment_Last; - Units.Table (Unum).Unit_Name := Uname_Actual; - - -- File was found - - if Src_Ind /= No_Source_File then - Units.Table (Unum) := ( - Cunit => Empty, - Cunit_Entity => Empty, - Dependency_Num => 0, - Dynamic_Elab => False, - Error_Location => Sloc (Error_Node), - Expected_Unit => Uname_Actual, - Fatal_Error => False, - Generate_Code => False, - Has_RACW => False, - Ident_String => Empty, - Loading => True, - Main_Priority => Default_Main_Priority, - Munit_Index => 0, - Serial_Number => 0, - Source_Index => Src_Ind, - Unit_File_Name => Fname, - Unit_Name => Uname_Actual, - Version => Source_Checksum (Src_Ind)); - - -- Parse the new unit - - declare - Save_Index : constant Nat := Multiple_Unit_Index; - begin - Multiple_Unit_Index := Get_Unit_Index (Uname_Actual); - Units.Table (Unum).Munit_Index := Multiple_Unit_Index; - Initialize_Scanner (Unum, Source_Index (Unum)); - Discard_List (Par (Configuration_Pragmas => False, - From_Limited_With => From_Limited_With)); - Multiple_Unit_Index := Save_Index; - Set_Loading (Unum, False); - end; - - -- If spec is irrelevant, then post errors and quit - - if Corr_Body /= No_Unit - and then Spec_Is_Irrelevant (Unum, Corr_Body) - then - Error_Msg_Name_1 := Unit_File_Name (Corr_Body); - Error_Msg - ("cannot compile subprogram in file {!", - Load_Msg_Sloc); - Error_Msg_Name_1 := Unit_File_Name (Unum); - Error_Msg - ("incorrect spec in file { must be removed first!", - Load_Msg_Sloc); - return No_Unit; - end if; - - -- If loaded unit had a fatal error, then caller inherits it! - - if Units.Table (Unum).Fatal_Error - and then Present (Error_Node) - then - Units.Table (Calling_Unit).Fatal_Error := True; - end if; - - -- Remove load stack entry and return the entry in the file table - - Load_Stack.Decrement_Last; - return Unum; - - -- Case of file not found - - else - if Debug_Flag_L then - Write_Str (" file was not found, load failed"); - Write_Eol; - end if; - - -- Generate message if unit required - - if Required and then Present (Error_Node) then - if Is_Predefined_File_Name (Fname) then - - -- This is a predefined library unit which is not present - -- in the run time. If a predefined unit is not available - -- it may very likely be the case that there is also pragma - -- Restriction forbidding its usage. This is typically the - -- case when building a configurable run time, where the - -- usage of certain run-time units units is restricted by - -- means of both the corresponding pragma Restriction (such - -- as No_Calendar), and by not including the unit. Hence, - -- we check whether this predefined unit is forbidden, so - -- that the message about the restriction violation is - -- generated, if needed. - - Check_Restricted_Unit (Load_Name, Error_Node); - - Error_Msg_Name_1 := Uname_Actual; - Error_Msg - ("% is not a predefined library unit", Load_Msg_Sloc); - - else - Error_Msg_Name_1 := Fname; - Error_Msg ("file{ not found", Load_Msg_Sloc); - end if; - - Write_Dependency_Chain; - - -- Remove unit from stack, to avoid cascaded errors on - -- subsequent missing files. - - Load_Stack.Decrement_Last; - Units.Decrement_Last; - - -- If unit not required, remove load stack entry and the junk - -- file table entry, and return No_Unit to indicate not found, - - else - Load_Stack.Decrement_Last; - Units.Decrement_Last; - end if; - - return No_Unit; - end if; - end if; - end Load_Unit; - - ------------------------ - -- Make_Instance_Unit -- - ------------------------ - - -- If the unit is an instance, it appears as a package declaration, but - -- contains both declaration and body of the instance. The body becomes - -- the main unit of the compilation, and the declaration is inserted - -- at the end of the unit table. The main unit now has the name of a - -- body, which is constructed from the name of the original spec, - -- and is attached to the compilation node of the original unit. The - -- declaration has been attached to a new compilation unit node, and - -- code will have to be generated for it. - - procedure Make_Instance_Unit (N : Node_Id) is - Sind : constant Source_File_Index := Source_Index (Main_Unit); - begin - Units.Increment_Last; - Units.Table (Units.Last) := Units.Table (Main_Unit); - Units.Table (Units.Last).Cunit := Library_Unit (N); - Units.Table (Units.Last).Generate_Code := True; - Units.Table (Main_Unit).Cunit := N; - Units.Table (Main_Unit).Unit_Name := - Get_Body_Name (Unit_Name (Get_Cunit_Unit_Number (Library_Unit (N)))); - Units.Table (Main_Unit).Version := Source_Checksum (Sind); - end Make_Instance_Unit; - - ------------------------ - -- Spec_Is_Irrelevant -- - ------------------------ - - function Spec_Is_Irrelevant - (Spec_Unit : Unit_Number_Type; - Body_Unit : Unit_Number_Type) return Boolean - is - Sunit : constant Node_Id := Cunit (Spec_Unit); - Bunit : constant Node_Id := Cunit (Body_Unit); - - begin - -- The spec is irrelevant if the body is a subprogram body, and the - -- spec is other than a subprogram spec or generic subprogram spec. - -- Note that the names must be the same, we don't need to check that, - -- because we already know that from the fact that the file names are - -- the same. - - return - Nkind (Unit (Bunit)) = N_Subprogram_Body - and then Nkind (Unit (Sunit)) /= N_Subprogram_Declaration - and then Nkind (Unit (Sunit)) /= N_Generic_Subprogram_Declaration; - end Spec_Is_Irrelevant; - - -------------------- - -- Version_Update -- - -------------------- - - procedure Version_Update (U : Node_Id; From : Node_Id) is - Unum : constant Unit_Number_Type := Get_Cunit_Unit_Number (U); - Fnum : constant Unit_Number_Type := Get_Cunit_Unit_Number (From); - begin - if Source_Index (Fnum) /= No_Source_File then - Units.Table (Unum).Version := - Units.Table (Unum).Version - xor - Source_Checksum (Source_Index (Fnum)); - end if; - end Version_Update; - - ---------------------------- - -- Write_Dependency_Chain -- - ---------------------------- - - procedure Write_Dependency_Chain is - begin - -- The dependency chain is only written if it is at least two entries - -- deep, otherwise it is trivial (the main unit depending on a unit - -- that it obviously directly depends on). - - if Load_Stack.Last - 1 > Load_Stack.First then - for U in Load_Stack.First .. Load_Stack.Last - 1 loop - Error_Msg_Unit_1 := - Unit_Name (Load_Stack.Table (U).Unit_Number); - Error_Msg_Unit_2 := - Unit_Name (Load_Stack.Table (U + 1).Unit_Number); - Error_Msg ("$ depends on $!", Load_Msg_Sloc); - end loop; - end if; - end Write_Dependency_Chain; - -end Lib.Load; |