-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2006, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2007, 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- --
-- The parameter Fnam is the name of the constructed function.
function Has_Stream_Standard_Rep (U_Type : Entity_Id) return Boolean;
- -- This function is used to test U_Type, which is a type
- -- Returns True if U_Type has a standard representation for stream
- -- purposes, i.e. there is no non-standard enumeration representation
- -- clause, and the size of the first subtype is the same as the size
- -- of the root type.
+ -- This function is used to test the type U_Type, to determine if it has
+ -- a standard representation from a streaming point of view. Standard means
+ -- that it has a standard representation (e.g. no enumeration rep clause),
+ -- and the size of the root type is the same as the streaming size (which
+ -- is defined as value specified by a Stream_Size clause if present, or
+ -- the Esize of U_Type if not).
function Make_Stream_Subprogram_Name
(Loc : Source_Ptr;
-- Compute the size of the stream element. This is either the size of
-- the first subtype or if given the size of the Stream_Size attribute.
- if Is_Elementary_Type (FST) and then Has_Stream_Size_Clause (FST) then
+ if Has_Stream_Size_Clause (FST) then
P_Size := Static_Integer (Expression (Stream_Size_Clause (FST)));
else
P_Size := Esize (FST);
-- Floating point types
elsif Is_Floating_Point_Type (U_Type) then
- if P_Size <= Standard_Short_Float_Size then
+
+ -- Question: should we use P_Size or Rt_Type to distinguish between
+ -- possible floating point types? If a non-standard size or a stream
+ -- size is specified, then we should certainly use the size. But if
+ -- we have two types the same (notably Short_Float_Size = Float_Size
+ -- which is close to universally true, and Long_Long_Float_Size =
+ -- Long_Float_Size, true on most targets except the x86), then we
+ -- would really rather use the root type, so that if people want to
+ -- fiddle with System.Stream_Attributes to get inter-target portable
+ -- streams, they get the size they expect. Consider in particular the
+ -- case of a stream written on an x86, with 96-bit Long_Long_Float
+ -- being read into a non-x86 target with 64 bit Long_Long_Float. A
+ -- special version of System.Stream_Attributes can deal with this
+ -- provided the proper type is always used.
+
+ -- To deal with these two requirements we add the special checks
+ -- on equal sizes and use the root type to distinguish.
+
+ if P_Size <= Standard_Short_Float_Size
+ and then (Standard_Short_Float_Size /= Standard_Float_Size
+ or else Rt_Type = Standard_Short_Float)
+ then
Lib_RE := RE_I_SF;
elsif P_Size <= Standard_Float_Size then
Lib_RE := RE_I_F;
- elsif P_Size <= Standard_Long_Float_Size then
+ elsif P_Size <= Standard_Long_Float_Size
+ and then (Standard_Long_Float_Size /= Standard_Long_Long_Float_Size
+ or else Rt_Type = Standard_Float)
+ then
Lib_RE := RE_I_LF;
else
-- Compute the size of the stream element. This is either the size of
-- the first subtype or if given the size of the Stream_Size attribute.
- if Is_Elementary_Type (FST) and then Has_Stream_Size_Clause (FST) then
+ if Has_Stream_Size_Clause (FST) then
P_Size := Static_Integer (Expression (Stream_Size_Clause (FST)));
else
P_Size := Esize (FST);
-- Floating point types
elsif Is_Floating_Point_Type (U_Type) then
- if P_Size <= Standard_Short_Float_Size then
+
+ -- Question: should we use P_Size or Rt_Type to distinguish between
+ -- possible floating point types? If a non-standard size or a stream
+ -- size is specified, then we should certainly use the size. But if
+ -- we have two types the same (notably Short_Float_Size = Float_Size
+ -- which is close to universally true, and Long_Long_Float_Size =
+ -- Long_Float_Size, true on most targets except the x86), then we
+ -- would really rather use the root type, so that if people want to
+ -- fiddle with System.Stream_Attributes to get inter-target portable
+ -- streams, they get the size they expect. Consider in particular the
+ -- case of a stream written on an x86, with 96-bit Long_Long_Float
+ -- being read into a non-x86 target with 64 bit Long_Long_Float. A
+ -- special version of System.Stream_Attributes can deal with this
+ -- provided the proper type is always used.
+
+ -- To deal with these two requirements we add the special checks
+ -- on equal sizes and use the root type to distinguish.
+
+ if P_Size <= Standard_Short_Float_Size
+ and then (Standard_Short_Float_Size /= Standard_Float_Size
+ or else Rt_Type = Standard_Short_Float)
+ then
Lib_RE := RE_W_SF;
+
elsif P_Size <= Standard_Float_Size then
Lib_RE := RE_W_F;
- elsif P_Size <= Standard_Long_Float_Size then
+
+ elsif P_Size <= Standard_Long_Float_Size
+ and then (Standard_Long_Float_Size /= Standard_Long_Long_Float_Size
+ or else Rt_Type = Standard_Float)
+ then
Lib_RE := RE_W_LF;
+
else
Lib_RE := RE_W_LLF;
end if;
-- type W is range -1 .. +254;
-- for W'Size use 8;
+ -- forcing a biased and unsigned representation
+
elsif not Is_Unsigned_Type (FST)
and then
(Is_Fixed_Point_Type (U_Type)
-- Loop through components, skipping all internal components,
-- which are not part of the value (e.g. _Tag), except that we
-- don't skip the _Parent, since we do want to process that
- -- recursively.
+ -- recursively. If _Parent is an interface type, being abstract
+ -- with no components there is no need to handle it.
while Present (Item) loop
if Nkind (Item) = N_Component_Declaration
and then
- (Chars (Defining_Identifier (Item)) = Name_uParent
+ ((Chars (Defining_Identifier (Item)) = Name_uParent
+ and then not Is_Interface
+ (Etype (Defining_Identifier (Item))))
or else
not Is_Internal_Name (Chars (Defining_Identifier (Item))))
then
-----------------------------
function Has_Stream_Standard_Rep (U_Type : Entity_Id) return Boolean is
+ Siz : Uint;
+
begin
if Has_Non_Standard_Rep (U_Type) then
return False;
+ end if;
+
+ if Has_Stream_Size_Clause (U_Type) then
+ Siz := Static_Integer (Expression (Stream_Size_Clause (U_Type)));
else
- return
- Esize (First_Subtype (U_Type)) = Esize (Root_Type (U_Type));
+ Siz := Esize (First_Subtype (U_Type));
end if;
+
+ return Siz = Esize (Root_Type (U_Type));
end Has_Stream_Standard_Rep;
---------------------------------