diff options
author | Javier Miranda <miranda@adacore.com> | 2005-07-04 15:28:59 +0200 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2005-07-04 15:28:59 +0200 |
commit | 60050a2df1113651408e5cb751cb5a3cb0ecbb42 (patch) | |
tree | 3717bc8812b8b73903c33eb719731940a8a4d388 /gcc | |
parent | c6bbcfff037aaa575fc55de8963d60b5dd124bda (diff) | |
download | gcc-60050a2df1113651408e5cb751cb5a3cb0ecbb42.zip gcc-60050a2df1113651408e5cb751cb5a3cb0ecbb42.tar.gz gcc-60050a2df1113651408e5cb751cb5a3cb0ecbb42.tar.bz2 |
par-load.adb: Load the context items in two rounds.
2005-07-04 Javier Miranda <miranda@adacore.com>
* par-load.adb: Load the context items in two rounds.
From-SVN: r101584
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ada/par-load.adb | 145 |
1 files changed, 87 insertions, 58 deletions
diff --git a/gcc/ada/par-load.adb b/gcc/ada/par-load.adb index cd99362..3d42506 100644 --- a/gcc/ada/par-load.adb +++ b/gcc/ada/par-load.adb @@ -87,6 +87,9 @@ procedure Load is Unum : Unit_Number_Type; -- Unit number of loaded unit + Limited_With_Found : Boolean := False; + -- Set True if a limited WITH is found, used to ??? + function Same_File_Name_Except_For_Case (Expected_File_Name : File_Name_Type; Actual_File_Name : File_Name_Type) return Boolean; @@ -350,83 +353,109 @@ begin Reset_Validity_Check_Options; end if; - -- Loop through context items + -- Load the context items in two rounds: the first round handles normal + -- withed units and the second round handles Ada 2005 limited-withed units. + -- This is required to allow the low-level circuitry that detects circular + -- dependencies of units the correct notification of the following error: - Context_Node := First (Context_Items (Curunit)); - while Present (Context_Node) loop - if Nkind (Context_Node) = N_With_Clause then - With_Node := Context_Node; - Spec_Name := Get_Unit_Name (With_Node); + -- limited with D; + -- with D; with C; + -- package C is ... package D is ... - Unum := - Load_Unit - (Load_Name => Spec_Name, - Required => False, - Subunit => False, - Error_Node => With_Node, - Renamings => True, - From_Limited_With => From_Limited_With - or else - Limited_Present (Context_Node)); - - -- If we find the unit, then set spec pointer in the N_With_Clause - -- to point to the compilation unit for the spec. Remember that - -- the Load routine itself sets our Fatal_Error flag if the loaded - -- unit gets a fatal error, so we don't need to worry about that. + for Round in 1 .. 2 loop + Context_Node := First (Context_Items (Curunit)); + while Present (Context_Node) loop - if Unum /= No_Unit then - Set_Library_Unit (With_Node, Cunit (Unum)); + -- During the first round we check if there is some limited-with + -- context clause; otherwise the second round will be skipped + + if Nkind (Context_Node) = N_With_Clause + and then Round = 1 + and then Limited_Present (Context_Node) + then + Limited_With_Found := True; + end if; - -- If the spec isn't found, then try finding the corresponding - -- body, since it is possible that we have a subprogram body - -- that is acting as a spec (since no spec is present). + if Nkind (Context_Node) = N_With_Clause + and then ((Round = 1 and then not Limited_Present (Context_Node)) + or else + (Round = 2 and then Limited_Present (Context_Node))) + then + With_Node := Context_Node; + Spec_Name := Get_Unit_Name (With_Node); - else - Body_Name := Get_Body_Name (Spec_Name); Unum := Load_Unit - (Load_Name => Body_Name, - Required => False, - Subunit => False, - Error_Node => With_Node, - Renamings => True); - - -- If we got a subprogram body, then mark that we are using - -- the body as a spec in the file table, and set the spec - -- pointer in the N_With_Clause to point to the body entity. - - if Unum /= No_Unit - and then Nkind (Unit (Cunit (Unum))) = N_Subprogram_Body - then - With_Cunit := Cunit (Unum); - Set_Library_Unit (With_Node, With_Cunit); - Set_Acts_As_Spec (With_Cunit, True); - Set_Library_Unit (With_Cunit, With_Cunit); + (Load_Name => Spec_Name, + Required => False, + Subunit => False, + Error_Node => With_Node, + Renamings => True, + From_Limited_With => From_Limited_With + or else + Limited_Present (Context_Node)); + + -- If we find the unit, then set spec pointer in the N_With_Clause + -- to point to the compilation unit for the spec. Remember that + -- the Load routine itself sets our Fatal_Error flag if the loaded + -- unit gets a fatal error, so we don't need to worry about that. + + if Unum /= No_Unit then + Set_Library_Unit (With_Node, Cunit (Unum)); - -- If we couldn't find the body, or if it wasn't a body spec - -- then we are in trouble. We make one more call to Load to - -- require the spec. We know it will fail of course, the - -- purpose is to generate the required error message (we prefer - -- that this message refer to the missing spec, not the body) + -- If the spec isn't found, then try finding the corresponding + -- body, since it is possible that we have a subprogram body + -- that is acting as a spec (since no spec is present). else + Body_Name := Get_Body_Name (Spec_Name); Unum := Load_Unit - (Load_Name => Spec_Name, - Required => True, + (Load_Name => Body_Name, + Required => False, Subunit => False, Error_Node => With_Node, Renamings => True); - -- Here we create a dummy package unit for the missing unit - - Unum := Create_Dummy_Package_Unit (With_Node, Spec_Name); - Set_Library_Unit (With_Node, Cunit (Unum)); + -- If we got a subprogram body, then mark that we are using + -- the body as a spec in the file table, and set the spec + -- pointer in the N_With_Clause to point to the body entity. + + if Unum /= No_Unit + and then Nkind (Unit (Cunit (Unum))) = N_Subprogram_Body + then + With_Cunit := Cunit (Unum); + Set_Library_Unit (With_Node, With_Cunit); + Set_Acts_As_Spec (With_Cunit, True); + Set_Library_Unit (With_Cunit, With_Cunit); + + -- If we couldn't find the body, or if it wasn't a body spec + -- then we are in trouble. We make one more call to Load to + -- require the spec. We know it will fail of course, the + -- purpose is to generate the required error message (we prefer + -- that this message refer to the missing spec, not the body) + + else + Unum := + Load_Unit + (Load_Name => Spec_Name, + Required => True, + Subunit => False, + Error_Node => With_Node, + Renamings => True); + + -- Here we create a dummy package unit for the missing unit + + Unum := Create_Dummy_Package_Unit (With_Node, Spec_Name); + Set_Library_Unit (With_Node, Cunit (Unum)); + end if; end if; end if; - end if; - Next (Context_Node); + Next (Context_Node); + end loop; + + exit when not Limited_With_Found; end loop; -- Restore style/validity check mode for main unit |