summaryrefslogtreecommitdiff
path: root/gcc/ada/ali.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/ali.adb')
-rw-r--r--gcc/ada/ali.adb227
1 files changed, 129 insertions, 98 deletions
diff --git a/gcc/ada/ali.adb b/gcc/ada/ali.adb
index 5a4c21bcffa..b654e32efc6 100644
--- a/gcc/ada/ali.adb
+++ b/gcc/ada/ali.adb
@@ -127,14 +127,14 @@ package body ALI is
function Get_Name (Lower : Boolean := False) return Name_Id;
-- Skip blanks, then scan out a name (name is left in Name_Buffer with
- -- length in Name_Len, as well as being returned in Name_Id form). The
- -- name is adjusted appropriately if it refers to a file that is to be
- -- substituted by another name as a result of a configuration pragma.
- -- If Lower is set to true then the Name_Buffer will be converted to
- -- all lower case. This only happends for systems where file names are
- -- not case sensitive, and ensures that gnatbind works correctly on
- -- such systems, regardless of the case of the file name. Note that
- -- a name can be terminated by a right typeref bracket or '='.
+ -- length in Name_Len, as well as being returned in Name_Id form).
+ -- If Lower is set to True then the Name_Buffer will be converted to
+ -- all lower case, for systems where file names are not case sensitive.
+ -- This ensures that gnatbind works correctly regardless of the case
+ -- of the file name on all systems. The name is terminated by a either
+ -- white space or a typeref bracket or an equal sign except for the
+ -- special case of an operator name starting with a double quite which
+ -- is terminated by another double quote.
function Get_Nat return Nat;
-- Skip blanks, then scan out an unsigned integer value in Nat range
@@ -305,11 +305,19 @@ package body ALI is
loop
Name_Len := Name_Len + 1;
Name_Buffer (Name_Len) := Getc;
- exit when At_End_Of_Field
- or else Nextc = ')'
- or else Nextc = '}'
- or else Nextc = '>'
- or else Nextc = '=';
+
+ exit when At_End_Of_Field;
+
+ if Name_Buffer (1) = '"' then
+ exit when Name_Len > 1 and then Name_Buffer (Name_Len) = '"';
+
+ else
+ exit when At_End_Of_Field
+ or else Nextc = '(' or else Nextc = ')'
+ or else Nextc = '{' or else Nextc = '}'
+ or else Nextc = '<' or else Nextc = '>'
+ or else Nextc = '=';
+ end if;
end loop;
-- Convert file name to all lower case if file names are not case
@@ -639,14 +647,25 @@ package body ALI is
Checkc (' ');
Skip_Space;
- for J in Partition_Restrictions loop
+ for J in All_Restrictions loop
C := Getc;
+ ALIs.Table (Id).Restrictions (J) := C;
- if C = 'v' or else C = 'r' or else C = 'n' then
- ALIs.Table (Id).Restrictions (J) := C;
- else
- Fatal_Error;
- end if;
+ case C is
+ when 'v' =>
+ Restrictions (J) := 'v';
+
+ when 'r' =>
+ if Restrictions (J) = 'n' then
+ Restrictions (J) := 'r';
+ end if;
+
+ when 'n' =>
+ null;
+
+ when others =>
+ Fatal_Error;
+ end case;
end loop;
if At_Eol then
@@ -694,6 +713,8 @@ package body ALI is
if Debug_Flag_U then
Write_Str (" ----> reading unit ");
+ Write_Int (Int (Units.Last));
+ Write_Str (" ");
Write_Unit_Name (Units.Table (Units.Last).Uname);
Write_Str (" from file ");
Write_Name (Units.Table (Units.Last).Sfile);
@@ -710,15 +731,22 @@ package body ALI is
and then Units.Table (Units.Last).Sfile /=
Units.Table (Unit_Id (Info)).Sfile
then
- -- If Err is set then treat duplicate unit name as an instance
- -- of a bad ALI format. This is the case of being called from
- -- gnatmake, and the point is that if anything is wrong with
- -- the ALI file, then gnatmake should just recompile.
+ -- If Err is set then ignore duplicate unit name. This is the
+ -- case of a call from gnatmake, where the situation can arise
+ -- from substitution of source files. In such situations, the
+ -- processing in gnatmake will always result in any required
+ -- recompilations in any case, and if we consider this to be
+ -- an error we get strange cases (for example when a generic
+ -- instantiation is replaced by a normal package) where we
+ -- read the old ali file, decide to recompile, and then decide
+ -- that the old and new ali files are incompatible.
if Err then
- raise Bad_ALI_Format;
+ null;
- -- If Err is not set, then this is a fatal error
+ -- If Err is not set, then this is a fatal error. This is
+ -- the case of being called from the binder, where we must
+ -- definitely diagnose this as an error.
else
Set_Standard_Error;
@@ -991,108 +1019,111 @@ package body ALI is
Units.Table (Units.Last).Last_With := Withs.Last;
Units.Table (Units.Last).Last_Arg := Args.Last;
- end loop Unit_Loop;
-
- -- End loop through units for one ALI file
+ -- If there are linker options lines present, scan them
- ALIs.Table (Id).Last_Unit := Units.Last;
- ALIs.Table (Id).Sfile := Units.Table (ALIs.Table (Id).First_Unit).Sfile;
+ Name_Len := 0;
- -- Set types of the units (there can be at most 2 of them)
+ Linker_Options_Loop : while C = 'L' loop
+ Checkc (' ');
+ Skip_Space;
+ Checkc ('"');
- if ALIs.Table (Id).First_Unit /= ALIs.Table (Id).Last_Unit then
- Units.Table (ALIs.Table (Id).First_Unit).Utype := Is_Body;
- Units.Table (ALIs.Table (Id).Last_Unit).Utype := Is_Spec;
+ loop
+ C := Getc;
- else
- -- Deal with body only and spec only cases, note that the reason we
- -- do our own checking of the name (rather than using Is_Body_Name)
- -- is that Uname drags in far too much compiler junk!
+ if C < Character'Val (16#20#)
+ or else C > Character'Val (16#7E#)
+ then
+ Fatal_Error;
- Get_Name_String (Units.Table (Units.Last).Uname);
+ elsif C = '{' then
+ C := Character'Val (0);
- if Name_Buffer (Name_Len) = 'b' then
- Units.Table (Units.Last).Utype := Is_Body_Only;
- else
- Units.Table (Units.Last).Utype := Is_Spec_Only;
- end if;
- end if;
+ declare
+ V : Natural;
- -- If there are linker options lines present, scan them
+ begin
+ V := 0;
+ for J in 1 .. 2 loop
+ C := Getc;
- while C = 'L' loop
- Checkc (' ');
- Skip_Space;
- Checkc ('"');
+ if C in '0' .. '9' then
+ V := V * 16 +
+ Character'Pos (C) - Character'Pos ('0');
- Name_Len := 0;
- loop
- C := Getc;
+ elsif C in 'A' .. 'F' then
+ V := V * 16 +
+ Character'Pos (C) - Character'Pos ('A') + 10;
- if C < Character'Val (16#20#)
- or else C > Character'Val (16#7E#)
- then
- Fatal_Error;
+ else
+ Fatal_Error;
+ end if;
+ end loop;
- elsif C = '{' then
- C := Character'Val (0);
+ Checkc ('}');
- declare
- V : Natural;
+ Add_Char_To_Name_Buffer (Character'Val (V));
+ end;
- begin
- V := 0;
- for J in 1 .. 2 loop
+ else
+ if C = '"' then
+ exit when Nextc /= '"';
C := Getc;
+ end if;
- if C in '0' .. '9' then
- V := V * 16 +
- Character'Pos (C) - Character'Pos ('0');
+ Add_Char_To_Name_Buffer (C);
+ end if;
+ end loop;
- elsif C in 'A' .. 'F' then
- V := V * 16 +
- Character'Pos (C) - Character'Pos ('A') + 10;
+ Add_Char_To_Name_Buffer (nul);
- else
- Fatal_Error;
- end if;
- end loop;
+ Skip_Eol;
+ C := Getc;
+ end loop Linker_Options_Loop;
- Checkc ('}');
+ -- Store the linker options entry
- Add_Char_To_Name_Buffer (Character'Val (V));
- end;
+ if Name_Len /= 0 then
+ Linker_Options.Increment_Last;
- else
- if C = '"' then
- exit when Nextc /= '"';
- C := Getc;
- end if;
+ Linker_Options.Table (Linker_Options.Last).Name :=
+ Name_Enter;
- Add_Char_To_Name_Buffer (C);
- end if;
- end loop;
+ Linker_Options.Table (Linker_Options.Last).Unit :=
+ Units.Last;
- Add_Char_To_Name_Buffer (nul);
+ Linker_Options.Table (Linker_Options.Last).Internal_File :=
+ Is_Internal_File_Name (F);
- Skip_Eol;
- C := Getc;
+ Linker_Options.Table (Linker_Options.Last).Original_Pos :=
+ Linker_Options.Last;
+ end if;
+ end loop Unit_Loop;
- Linker_Options.Increment_Last;
+ -- End loop through units for one ALI file
- Linker_Options.Table (Linker_Options.Last).Name
- := Name_Enter;
+ ALIs.Table (Id).Last_Unit := Units.Last;
+ ALIs.Table (Id).Sfile := Units.Table (ALIs.Table (Id).First_Unit).Sfile;
- Linker_Options.Table (Linker_Options.Last).Unit
- := ALIs.Table (Id).First_Unit;
+ -- Set types of the units (there can be at most 2 of them)
- Linker_Options.Table (Linker_Options.Last).Internal_File
- := Is_Internal_File_Name (F);
+ if ALIs.Table (Id).First_Unit /= ALIs.Table (Id).Last_Unit then
+ Units.Table (ALIs.Table (Id).First_Unit).Utype := Is_Body;
+ Units.Table (ALIs.Table (Id).Last_Unit).Utype := Is_Spec;
+
+ else
+ -- Deal with body only and spec only cases, note that the reason we
+ -- do our own checking of the name (rather than using Is_Body_Name)
+ -- is that Uname drags in far too much compiler junk!
- Linker_Options.Table (Linker_Options.Last).Original_Pos
- := Linker_Options.Last;
+ Get_Name_String (Units.Table (Units.Last).Uname);
- end loop;
+ if Name_Buffer (Name_Len) = 'b' then
+ Units.Table (Units.Last).Utype := Is_Body_Only;
+ else
+ Units.Table (Units.Last).Utype := Is_Spec_Only;
+ end if;
+ end if;
-- Scan out external version references and put in hash table