diff --git a/gcc/ada/contracts.adb b/gcc/ada/contracts.adb index 9fc9e05db68..a93bf622aa1 100644 --- a/gcc/ada/contracts.adb +++ b/gcc/ada/contracts.adb @@ -546,33 +546,41 @@ package body Contracts is begin -- Move through the body's declarations analyzing all pragmas which - -- appear at the top of the declarations. + -- appear at the top of the declarations. Go over the list twice, so + -- that pragmas which should be analyzed first are analyzed in the + -- first pass. - Curr_Decl := First (Declarations (Unit_Declaration_Node (Body_Id))); - while Present (Curr_Decl) loop + for Pragmas_Analyzed_First in reverse False .. True loop - if Nkind (Curr_Decl) = N_Pragma then + Curr_Decl := First (Declarations (Unit_Declaration_Node (Body_Id))); + while Present (Curr_Decl) loop - if Pragma_Significant_To_Subprograms - (Get_Pragma_Id (Curr_Decl)) - then - Analyze (Curr_Decl); + if Nkind (Curr_Decl) = N_Pragma then + + if Pragma_Significant_To_Subprograms + (Get_Pragma_Id (Curr_Decl)) + and then Pragmas_Analyzed_First = + Pragma_Significant_To_Subprograms_Analyzed_First + (Get_Pragma_Id (Curr_Decl)) + then + Analyze (Curr_Decl); + end if; + + -- Skip the renamings of discriminants and protection fields + + elsif Is_Prologue_Renaming (Curr_Decl) then + null; + + -- We have reached something which is not a pragma so we can be + -- sure there are no more contracts or pragmas which need to be + -- taken into account. + + else + exit; end if; - -- Skip the renamings of discriminants and protection fields - - elsif Is_Prologue_Renaming (Curr_Decl) then - null; - - -- We have reached something which is not a pragma so we can be sure - -- there are no more contracts or pragmas which need to be taken into - -- account. - - else - exit; - end if; - - Next (Curr_Decl); + Next (Curr_Decl); + end loop; end loop; end Analyze_Pragmas_In_Declarations; diff --git a/gcc/ada/einfo-utils.ads b/gcc/ada/einfo-utils.ads index 01953c35bc3..8207576fb89 100644 --- a/gcc/ada/einfo-utils.ads +++ b/gcc/ada/einfo-utils.ads @@ -448,6 +448,7 @@ package Einfo.Utils is -- Effective_Reads -- Effective_Writes -- Exceptional_Cases + -- Extensions_Visible -- Global -- Initial_Condition -- Initializes diff --git a/gcc/ada/sem_prag.ads b/gcc/ada/sem_prag.ads index 59220ea890c..557e0454870 100644 --- a/gcc/ada/sem_prag.ads +++ b/gcc/ada/sem_prag.ads @@ -216,6 +216,7 @@ package Sem_Prag is Pragma_Contract_Cases => True, Pragma_Depends => True, Pragma_Exceptional_Cases => True, + Pragma_Extensions_Visible => True, Pragma_Ghost => True, Pragma_Global => True, Pragma_Inline => True, @@ -238,6 +239,15 @@ package Sem_Prag is Pragma_Volatile_Function => True, others => False); + -- The following table lists all pragmas which are relevant to the analysis + -- of subprogram bodies and should be analyzed first, because the analysis + -- of other pragmas relevant to subprogram bodies depend on them. + + Pragma_Significant_To_Subprograms_Analyzed_First : + constant array (Pragma_Id) of Boolean := + (Pragma_Extensions_Visible => True, + others => False); + ----------------- -- Subprograms -- -----------------