From: Vincent Celier Date: Mon, 4 Aug 2008 09:17:44 +0000 (+0000) Subject: gprep.adb (Process_One_File): Call Prep.Preprocess with a Boolean variable... X-Git-Tag: releases/gcc-4.4.0~3435 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a037f912464e14216f579eccc996d7565a697433;p=thirdparty%2Fgcc.git gprep.adb (Process_One_File): Call Prep.Preprocess with a Boolean variable... 2008-08-04 Vincent Celier * gprep.adb (Process_One_File): Call Prep.Preprocess with a Boolean variable, but don't check the resulting value as it has no impact on the processing. * opt.ads: (Generate_Processed_File): New Boolean flag, set to True in the compiler when switch -gnateG is used. * prep.adb: (Preprocess): new Boolean out parameter Source_Modified. Set it to True when the source is modified by the preprocessor and there is no preprocessing errors. * prep.ads (Preprocess): new Boolean out parameter Source_Modified * sinput-l.adb: (Load_File): Output the result of preprocessing if the source text was modified. * switch-c.adb (Scan_Front_End_Switches): Recognize switch -gnateG * switch-m.adb (Normalize_Compiler_Switches): Normalize switch -gnateG * ug_words: Add VMS equivalent for -gnateG * vms_data.ads: Add VMS option /GENERATE_PROCESSED_SOURCE, equivalent to switch -gnateG From-SVN: r138590 --- diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 65cc4f0b00d6..909e815cc273 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,33 @@ +2008-08-04 Vincent Celier + + * gprep.adb (Process_One_File): Call Prep.Preprocess with a Boolean + variable, but don't check the resulting value as it has no impact on + the processing. + + * opt.ads: + (Generate_Processed_File): New Boolean flag, set to True in the compiler + when switch -gnateG is used. + + * prep.adb: + (Preprocess): new Boolean out parameter Source_Modified. Set it to True + when the source is modified by the preprocessor and there is no + preprocessing errors. + + * prep.ads (Preprocess): new Boolean out parameter Source_Modified + + * sinput-l.adb: + (Load_File): Output the result of preprocessing if the source text was + modified. + + * switch-c.adb (Scan_Front_End_Switches): Recognize switch -gnateG + + * switch-m.adb (Normalize_Compiler_Switches): Normalize switch -gnateG + + * ug_words: Add VMS equivalent for -gnateG + + * vms_data.ads: + Add VMS option /GENERATE_PROCESSED_SOURCE, equivalent to switch -gnateG + 2008-08-04 Doug Rupp * gcc-interface/utils2.c: diff --git a/gcc/ada/gprep.adb b/gcc/ada/gprep.adb index 040a726f572d..44633b9c902c 100644 --- a/gcc/ada/gprep.adb +++ b/gcc/ada/gprep.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2002-2007, Free Software Foundation, Inc. -- +-- Copyright (C) 2002-2008, 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- -- @@ -475,6 +475,9 @@ package body GPrep is procedure Process_One_File is Infile : Source_File_Index; + Modified : Boolean; + pragma Warnings (Off, Modified); + begin -- Create the output file (fails if this does not work) @@ -515,7 +518,7 @@ package body GPrep is -- Preprocess the input file - Prep.Preprocess; + Prep.Preprocess (Modified); -- In verbose mode, if there is no error, report it diff --git a/gcc/ada/opt.ads b/gcc/ada/opt.ads index 600231c737ac..68bf246919ac 100644 --- a/gcc/ada/opt.ads +++ b/gcc/ada/opt.ads @@ -528,6 +528,11 @@ package Opt is -- the name is of the form .xxx, then to name.xxx where name is the source -- file name with extension stripped. + Generate_Processed_File : Boolean := False; + -- GNAT + -- True when switch -gnateG is used. When True, create in a file + -- .prep, if the source is preprocessed. + Generating_Code : Boolean := False; -- GNAT -- True if the frontend finished its work and has called the backend to diff --git a/gcc/ada/prep.adb b/gcc/ada/prep.adb index eb739a752745..c1f4a5e780bc 100644 --- a/gcc/ada/prep.adb +++ b/gcc/ada/prep.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2002-2007, Free Software Foundation, Inc. -- +-- Copyright (C) 2002-2008, 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- -- @@ -1043,10 +1043,12 @@ package body Prep is -- Preprocess -- ---------------- - procedure Preprocess is + procedure Preprocess (Source_Modified : out Boolean) is Start_Of_Processing : Source_Ptr; Cond : Boolean; Preprocessor_Line : Boolean := False; + No_Error_Found : Boolean := True; + Modified : Boolean := False; procedure Output (From, To : Source_Ptr); -- Output the characters with indices From .. To in the buffer @@ -1118,75 +1120,21 @@ package body Prep is -- Preprocessor line if Token = Tok_Special and then Special_Character = '#' then - Preprocessor_Line := True; - Scan.all; - - case Token is - - -- #if - - when Tok_If => - declare - If_Ptr : constant Source_Ptr := Token_Ptr; - - begin - Scan.all; - Cond := Expression (not Deleting); - - -- Check for an eventual "then" - - if Token = Tok_Then then - Scan.all; - end if; - - -- It is an error to have trailing characters after - -- the condition or "then". - - if Token /= Tok_End_Of_Line - and then Token /= Tok_EOF - then - Error_Msg - ("extraneous text on preprocessor line", - Token_Ptr); - Go_To_End_Of_Line; - end if; - - declare - -- Set the initial state of this new "#if". - -- This must be done before incrementing the - -- Last of the table, otherwise function - -- Deleting does not report the correct value. - - New_State : constant Pp_State := - (If_Ptr => If_Ptr, - Else_Ptr => 0, - Deleting => Deleting or (not Cond), - Match_Seen => Deleting or Cond); - - begin - Pp_States.Increment_Last; - Pp_States.Table (Pp_States.Last) := New_State; - end; - end; - - -- #elsif + Modified := True; + Preprocessor_Line := True; + Scan.all; - when Tok_Elsif => - Cond := False; + case Token is - if Pp_States.Last = 0 - or else Pp_States.Table (Pp_States.Last).Else_Ptr - /= 0 - then - Error_Msg ("no IF for this ELSIF", Token_Ptr); + -- #if - else - Cond := - not Pp_States.Table (Pp_States.Last).Match_Seen; - end if; + when Tok_If => + declare + If_Ptr : constant Source_Ptr := Token_Ptr; + begin Scan.all; - Cond := Expression (Cond); + Cond := Expression (not Deleting); -- Check for an eventual "then" @@ -1203,136 +1151,201 @@ package body Prep is Error_Msg ("extraneous text on preprocessor line", Token_Ptr); - + No_Error_Found := False; Go_To_End_Of_Line; end if; - -- Depending on the value of the condition, set the - -- new values of Deleting and Match_Seen. - if Pp_States.Last > 0 then - if Pp_States.Table (Pp_States.Last).Match_Seen then - Pp_States.Table (Pp_States.Last).Deleting := - True; - else - if Cond then - Pp_States.Table (Pp_States.Last).Match_Seen := - True; - Pp_States.Table (Pp_States.Last).Deleting := - False; - end if; - end if; - end if; + declare + -- Set the initial state of this new "#if". This + -- must be done before incrementing the Last of + -- the table, otherwise function Deleting does + -- not report the correct value. - -- #else + New_State : constant Pp_State := + (If_Ptr => If_Ptr, + Else_Ptr => 0, + Deleting => Deleting or (not Cond), + Match_Seen => Deleting or Cond); - when Tok_Else => - if Pp_States.Last = 0 then - Error_Msg ("no IF for this ELSE", Token_Ptr); + begin + Pp_States.Increment_Last; + Pp_States.Table (Pp_States.Last) := New_State; + end; + end; - elsif - Pp_States.Table (Pp_States.Last).Else_Ptr /= 0 - then - Error_Msg ("duplicate ELSE line", Token_Ptr); - end if; + -- #elsif - -- Set the possibly new values of Deleting and - -- Match_Seen. + when Tok_Elsif => + Cond := False; - if Pp_States.Last > 0 then - if Pp_States.Table (Pp_States.Last).Match_Seen then - Pp_States.Table (Pp_States.Last).Deleting := - True; + if Pp_States.Last = 0 + or else Pp_States.Table (Pp_States.Last).Else_Ptr /= 0 + then + Error_Msg ("no IF for this ELSIF", Token_Ptr); + No_Error_Found := False; - else + else + Cond := + not Pp_States.Table (Pp_States.Last).Match_Seen; + end if; + + Scan.all; + Cond := Expression (Cond); + + -- Check for an eventual "then" + + if Token = Tok_Then then + Scan.all; + end if; + + -- It is an error to have trailing characters after + -- the condition or "then". + + if Token /= Tok_End_Of_Line + and then Token /= Tok_EOF + then + Error_Msg + ("extraneous text on preprocessor line", + Token_Ptr); + No_Error_Found := False; + + Go_To_End_Of_Line; + end if; + + -- Depending on the value of the condition, set the + -- new values of Deleting and Match_Seen. + if Pp_States.Last > 0 then + if Pp_States.Table (Pp_States.Last).Match_Seen then + Pp_States.Table (Pp_States.Last).Deleting := True; + else + if Cond then Pp_States.Table (Pp_States.Last).Match_Seen := True; Pp_States.Table (Pp_States.Last).Deleting := False; end if; + end if; + end if; - -- Set the Else_Ptr to check for illegal #elsif - -- later. + -- #else - Pp_States.Table (Pp_States.Last).Else_Ptr := - Token_Ptr; - end if; + when Tok_Else => + if Pp_States.Last = 0 then + Error_Msg ("no IF for this ELSE", Token_Ptr); + No_Error_Found := False; - Scan.all; + elsif + Pp_States.Table (Pp_States.Last).Else_Ptr /= 0 + then + Error_Msg ("duplicate ELSE line", Token_Ptr); + No_Error_Found := False; + end if; - -- It is an error to have characters after "#else" - if Token /= Tok_End_Of_Line - and then Token /= Tok_EOF - then - Error_Msg - ("extraneous text on preprocessor line", - Token_Ptr); - Go_To_End_Of_Line; - end if; + -- Set the possibly new values of Deleting and + -- Match_Seen. - -- #end if; + if Pp_States.Last > 0 then + if Pp_States.Table (Pp_States.Last).Match_Seen then + Pp_States.Table (Pp_States.Last).Deleting := + True; - when Tok_End => - if Pp_States.Last = 0 then - Error_Msg ("no IF for this END", Token_Ptr); + else + Pp_States.Table (Pp_States.Last).Match_Seen := + True; + Pp_States.Table (Pp_States.Last).Deleting := + False; end if; + -- Set the Else_Ptr to check for illegal #elsif + -- later. + + Pp_States.Table (Pp_States.Last).Else_Ptr := + Token_Ptr; + end if; + + Scan.all; + + -- It is an error to have characters after "#else" + if Token /= Tok_End_Of_Line + and then Token /= Tok_EOF + then + Error_Msg + ("extraneous text on preprocessor line", + Token_Ptr); + No_Error_Found := False; + Go_To_End_Of_Line; + end if; + + -- #end if; + + when Tok_End => + if Pp_States.Last = 0 then + Error_Msg ("no IF for this END", Token_Ptr); + No_Error_Found := False; + end if; + + Scan.all; + + if Token /= Tok_If then + Error_Msg ("IF expected", Token_Ptr); + No_Error_Found := False; + + else Scan.all; - if Token /= Tok_If then - Error_Msg ("IF expected", Token_Ptr); + if Token /= Tok_Semicolon then + Error_Msg ("`;` Expected", Token_Ptr); + No_Error_Found := False; else Scan.all; - if Token /= Tok_Semicolon then - Error_Msg ("`;` Expected", Token_Ptr); - - else - Scan.all; - - -- It is an error to have character after - -- "#end if;". - if Token /= Tok_End_Of_Line - and then Token /= Tok_EOF - then - Error_Msg - ("extraneous text on preprocessor line", - Token_Ptr); - end if; + -- It is an error to have character after + -- "#end if;". + if Token /= Tok_End_Of_Line + and then Token /= Tok_EOF + then + Error_Msg + ("extraneous text on preprocessor line", + Token_Ptr); + No_Error_Found := False; end if; end if; + end if; - -- In case of one of the errors above, skip the tokens - -- until the end of line is reached. + -- In case of one of the errors above, skip the tokens + -- until the end of line is reached. - Go_To_End_Of_Line; + Go_To_End_Of_Line; - -- Decrement the depth of the #if stack + -- Decrement the depth of the #if stack - if Pp_States.Last > 0 then - Pp_States.Decrement_Last; - end if; + if Pp_States.Last > 0 then + Pp_States.Decrement_Last; + end if; - -- Illegal preprocessor line + -- Illegal preprocessor line - when others => - if Pp_States.Last = 0 then - Error_Msg ("IF expected", Token_Ptr); + when others => + No_Error_Found := False; - elsif - Pp_States.Table (Pp_States.Last).Else_Ptr = 0 - then - Error_Msg ("IF, ELSIF, ELSE, or `END IF` expected", - Token_Ptr); + if Pp_States.Last = 0 then + Error_Msg ("IF expected", Token_Ptr); - else - Error_Msg ("IF or `END IF` expected", Token_Ptr); - end if; + elsif + Pp_States.Table (Pp_States.Last).Else_Ptr = 0 + then + Error_Msg ("IF, ELSIF, ELSE, or `END IF` expected", + Token_Ptr); + + else + Error_Msg ("IF or `END IF` expected", Token_Ptr); + end if; - -- Skip to the end of this illegal line + -- Skip to the end of this illegal line - Go_To_End_Of_Line; - end case; + Go_To_End_Of_Line; + end case; -- Not a preprocessor line @@ -1352,6 +1365,8 @@ package body Prep is if Token = Tok_Special and then Special_Character = '$' then + Modified := True; + declare Dollar_Ptr : constant Source_Ptr := Token_Ptr; Symbol : Symbol_Id; @@ -1449,7 +1464,10 @@ package body Prep is for Level in reverse 1 .. Pp_States.Last loop Error_Msg ("no `END IF` for this IF", Pp_States.Table (Level).If_Ptr); + No_Error_Found := False; end loop; + + Source_Modified := No_Error_Found and Modified; end Preprocess; end Prep; diff --git a/gcc/ada/prep.ads b/gcc/ada/prep.ads index 198ddb4159f2..0f595e64dfbd 100644 --- a/gcc/ada/prep.ads +++ b/gcc/ada/prep.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2002-2007, Free Software Foundation, Inc. -- +-- Copyright (C) 2002-2008, 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- -- @@ -106,9 +106,10 @@ package Prep is -- Parse the definition file. The definition file must have already been -- loaded and the scanner initialized. - procedure Preprocess; + procedure Preprocess (Source_Modified : out Boolean); -- Preprocess the input file. The input file must have already been loaded - -- and the scanner initialized. + -- and the scanner initialized. Source_Modified is set to True iff the + -- preprocessor modified the source text. procedure Check_Command_Line_Symbol_Definition (Definition : String; diff --git a/gcc/ada/sinput-l.adb b/gcc/ada/sinput-l.adb index eee61f664e05..8bb6778fbd77 100644 --- a/gcc/ada/sinput-l.adb +++ b/gcc/ada/sinput-l.adb @@ -28,6 +28,8 @@ with Atree; use Atree; with Debug; use Debug; with Einfo; use Einfo; with Errout; use Errout; +with Fname; use Fname; +with Hostparm; with Opt; use Opt; with Osint; use Osint; with Output; use Output; @@ -39,6 +41,8 @@ with Sinfo; use Sinfo; with Snames; use Snames; with System; use System; +with System.OS_Lib; use System.OS_Lib; + with Unchecked_Conversion; package body Sinput.L is @@ -319,7 +323,7 @@ package body Sinput.L is -- source will be the last created, and we will be able to replace it -- and modify Hi without stepping on another buffer. - if T = Osint.Source then + if T = Osint.Source and then not Is_Internal_File_Name (N) then Prepare_To_Preprocess (Source => N, Preprocessing_Needed => Preprocessing_Needed); end if; @@ -475,6 +479,8 @@ package body Sinput.L is -- Saved state of the Style_Check flag (which needs to be -- temporarily set to False during preprocessing, see below). + Modified : Boolean; + begin -- If this is the first time we preprocess a source, allocate -- the preprocessing buffer. @@ -512,7 +518,7 @@ package body Sinput.L is Save_Style_Check := Opt.Style_Check; Opt.Style_Check := False; - Preprocess; + Preprocess (Modified); -- Reset the scanner to its standard behavior, and restore the -- Style_Checks flag. @@ -531,6 +537,54 @@ package body Sinput.L is return No_Source_File; else + -- Output the result of the preprocessing, if requested and + -- the source has been modified by the preprocessing. + + if Generate_Processed_File and then Modified then + declare + FD : File_Descriptor; + NB : Integer; + Status : Boolean; + + begin + Get_Name_String (N); + + if Hostparm.OpenVMS then + Add_Str_To_Name_Buffer ("_prep"); + else + Add_Str_To_Name_Buffer (".prep"); + end if; + + Delete_File (Name_Buffer (1 .. Name_Len), Status); + + FD := + Create_New_File (Name_Buffer (1 .. Name_Len), Text); + + Status := FD /= Invalid_FD; + + if Status then + NB := + Write + (FD, + Prep_Buffer (1)'Address, + Integer (Prep_Buffer_Last)); + Status := NB = Integer (Prep_Buffer_Last); + end if; + + if Status then + Close (FD, Status); + end if; + + if not Status then + Errout.Error_Msg + ("could not write processed file """ & + Name_Buffer (1 .. Name_Len) & '"', + Lo); + return No_Source_File; + end if; + end; + end if; + -- Set the new value of Hi Hi := Lo + Source_Ptr (Prep_Buffer_Last); diff --git a/gcc/ada/switch-c.adb b/gcc/ada/switch-c.adb index cf59c8198cdc..63a1a6d83aae 100644 --- a/gcc/ada/switch-c.adb +++ b/gcc/ada/switch-c.adb @@ -371,6 +371,16 @@ package body Switch.C is Full_Path_Name_For_Brief_Errors := True; return; + -- -gnateG (save preprocessor output) + + when 'G' => + if Ptr < Max then + Bad_Switch (Switch_Chars); + end if; + + Generate_Processed_File := True; + Ptr := Ptr + 1; + -- -gnateI (index of unit in multi-unit source) when 'I' => diff --git a/gcc/ada/switch-m.adb b/gcc/ada/switch-m.adb index 20761f417cdc..7be075d98962 100644 --- a/gcc/ada/switch-m.adb +++ b/gcc/ada/switch-m.adb @@ -267,14 +267,16 @@ package body Switch.M is when 'e' => - -- Only -gnateD and -gnatep= need storing in ALI file + -- Store -gnateD, -gnatep= and -gnateG in the ALI file. + -- The other -gnate switches do not need to be stored. Storing (First_Stored) := 'e'; Ptr := Ptr + 1; if Ptr > Max or else (Switch_Chars (Ptr) /= 'D' - and then Switch_Chars (Ptr) /= 'p') + and then Switch_Chars (Ptr) /= 'G' + and then Switch_Chars (Ptr) /= 'p') then Last := 0; return; @@ -292,7 +294,7 @@ package body Switch.M is -- Processing for -gnatep= - else + elsif Switch_Chars (Ptr) = 'p' then Ptr := Ptr + 1; if Ptr = Max then @@ -316,6 +318,9 @@ package body Switch.M is Switch_Chars (Ptr .. Max); Add_Switch_Component (To_Store); end; + + elsif Switch_Chars (Ptr) = 'G' then + Add_Switch_Component ("-gnateG"); end if; return; diff --git a/gcc/ada/ug_words b/gcc/ada/ug_words index 7f8e9577e864..2cab6da2deaa 100644 --- a/gcc/ada/ug_words +++ b/gcc/ada/ug_words @@ -61,6 +61,7 @@ gcc -c ^ GNAT COMPILE -gnatec ^ /CONFIGURATION_PRAGMAS_FILE -gnateD ^ /SYMBOL_PREPROCESSING -gnatef ^ /FULL_PATH_IN_BRIEF_MESSAGES +-gnateG ^ /GENERATE_PROCESSED_SOURCE -gnatem ^ /MAPPING_FILE -gnatep ^ /DATA_PREPROCESSING -gnatE ^ /CHECKS=ELABORATION diff --git a/gcc/ada/vms_data.ads b/gcc/ada/vms_data.ads index 9f78cf72d33f..63ba1df8d05c 100644 --- a/gcc/ada/vms_data.ads +++ b/gcc/ada/vms_data.ads @@ -1526,6 +1526,14 @@ package VMS_Data is -- /VERBOSE), then error lines start with the full path name of the -- project file, rather than its simple file name. + S_GCC_Generate : aliased constant S := "/GENERATE_PROCESSED_SOURCE " & + "-gnateG"; + -- /NOGENERATE_PROCESSED_SOURCE (D) + -- /GENERATE_PROCESSED_SOURCE + -- + -- Generate a file _prep if the integrated preprocessing + -- is modifying the source text. + S_GCC_GNAT : aliased constant S := "/GNAT_INTERNAL " & "-gnatg"; -- /NOGNAT_INTERNAL (D) @@ -3311,6 +3319,7 @@ package VMS_Data is S_GCC_Follow 'Access, S_GCC_Force 'Access, S_GCC_Full 'Access, + S_GCC_Generate'Access, S_GCC_GNAT 'Access, S_GCC_Help 'Access, S_GCC_Ident 'Access,