end if;
end;
- ---------------
- -- Lock_Free --
- ---------------
-
- -- Rewrite the attribute reference with the value of Uses_Lock_Free
-
- when Attribute_Lock_Free => Lock_Free : declare
- V : constant Entity_Id := Boolean_Literals (Uses_Lock_Free (Ptyp));
- begin
- Rewrite (N, New_Occurrence_Of (V, Loc));
- Analyze_And_Resolve (N, Standard_Boolean);
- end Lock_Free;
-
-------------
-- Machine --
-------------
when Attribute_Abort_Signal |
Attribute_Address_Size |
+ Attribute_Atomic_Always_Lock_Free |
Attribute_Base |
Attribute_Class |
Attribute_Compiler_Version |
Attribute_Has_Tagged_Values |
Attribute_Large |
Attribute_Last_Valid |
+ Attribute_Lock_Free |
Attribute_Machine_Emax |
Attribute_Machine_Emin |
Attribute_Machine_Mantissa |
function Lock_Free_Read_8 (Ptr : Address) return uint8 is
begin
- if Support_Atomic_Primitives then
+ if uint8'Atomic_Always_Lock_Free then
return Atomic_Load_8 (Ptr, Acquire);
else
raise Program_Error;
function Lock_Free_Read_16 (Ptr : Address) return uint16 is
begin
- if Support_Atomic_Primitives then
+ if uint16'Atomic_Always_Lock_Free then
return Atomic_Load_16 (Ptr, Acquire);
else
raise Program_Error;
function Lock_Free_Read_32 (Ptr : Address) return uint32 is
begin
- if Support_Atomic_Primitives then
+ if uint32'Atomic_Always_Lock_Free then
return Atomic_Load_32 (Ptr, Acquire);
else
raise Program_Error;
function Lock_Free_Read_64 (Ptr : Address) return uint64 is
begin
- if Support_Atomic_Primitives then
+ if uint64'Atomic_Always_Lock_Free then
return Atomic_Load_64 (Ptr, Acquire);
else
raise Program_Error;
begin
if Expected /= Desired then
- if Support_Atomic_Primitives then
+ if uint8'Atomic_Always_Lock_Free then
Actual := Sync_Compare_And_Swap_8 (Ptr, Expected, Desired);
else
raise Program_Error;
begin
if Expected /= Desired then
- if Support_Atomic_Primitives then
+ if uint16'Atomic_Always_Lock_Free then
Actual := Sync_Compare_And_Swap_16 (Ptr, Expected, Desired);
else
raise Program_Error;
begin
if Expected /= Desired then
- if Support_Atomic_Primitives then
+ if uint32'Atomic_Always_Lock_Free then
Actual := Sync_Compare_And_Swap_32 (Ptr, Expected, Desired);
else
raise Program_Error;
begin
if Expected /= Desired then
- if Support_Atomic_Primitives then
+ if uint64'Atomic_Always_Lock_Free then
Actual := Sync_Compare_And_Swap_64 (Ptr, Expected, Desired);
else
raise Program_Error;
Set_Etype (N, RTE (RE_AST_Handler));
end AST_Entry;
+ -----------------------------
+ -- Atomic_Always_Lock_Free --
+ -----------------------------
+
+ when Attribute_Atomic_Always_Lock_Free =>
+ Check_E0;
+ Check_Type;
+ Set_Etype (N, Standard_Boolean);
+
----------
-- Base --
----------
return;
end if;
+ -- For Lock_Free, we apply the attribute to the type of the object.
+ -- This is allowed since we have already verified that the type is a
+ -- protected type.
+
+ elsif Id = Attribute_Lock_Free then
+ P_Entity := Etype (P);
+
-- No other attributes for objects are folded
else
-- Definite must be folded if the prefix is not a generic type,
-- that is to say if we are within an instantiation. Same processing
- -- applies to the GNAT attributes Has_Discriminants, Type_Class,
- -- Has_Tagged_Value, and Unconstrained_Array.
+ -- applies to the GNAT attributes Atomic_Always_Lock_Free,
+ -- Has_Discriminants, Lock_Free, Type_Class, Has_Tagged_Value, and
+ -- Unconstrained_Array.
- elsif (Id = Attribute_Definite
+ elsif (Id = Attribute_Atomic_Always_Lock_Free
+ or else
+ Id = Attribute_Definite
or else
Id = Attribute_Has_Access_Values
or else
or else
Id = Attribute_Has_Tagged_Values
or else
+ Id = Attribute_Lock_Free
+ or else
Id = Attribute_Type_Class
or else
Id = Attribute_Unconstrained_Array
-- since we can't do anything with unconstrained arrays. In addition,
-- only the First, Last and Length attributes are possibly static.
- -- Definite, Has_Access_Values, Has_Discriminants, Has_Tagged_Values,
- -- Type_Class, and Unconstrained_Array are again exceptions, because
- -- they apply as well to unconstrained types.
+ -- Atomic_Always_Lock_Free, Definite, Has_Access_Values,
+ -- Has_Discriminants, Has_Tagged_Values, Lock_Free, Type_Class, and
+ -- Unconstrained_Array are again exceptions, because they apply as well
+ -- to unconstrained types.
-- In addition Component_Size is an exception since it is possibly
-- foldable, even though it is never static, and it does apply to
-- unconstrained arrays. Furthermore, it is essential to fold this
-- in the packed case, since otherwise the value will be incorrect.
- elsif Id = Attribute_Definite
+ elsif Id = Attribute_Atomic_Always_Lock_Free
+ or else
+ Id = Attribute_Definite
or else
Id = Attribute_Has_Access_Values
or else
or else
Id = Attribute_Has_Tagged_Values
or else
+ Id = Attribute_Lock_Free
+ or else
Id = Attribute_Type_Class
or else
Id = Attribute_Unconstrained_Array
null;
end if;
+ -----------------------------
+ -- Atomic_Always_Lock_Free --
+ -----------------------------
+
+ -- Atomic_Always_Lock_Free attribute is a Boolean, thus no need to fold
+ -- here.
+
+ when Attribute_Atomic_Always_Lock_Free => Atomic_Always_Lock_Free :
+ declare
+ V : constant Entity_Id :=
+ Boolean_Literals
+ (Support_Atomic_Primitives_On_Target
+ and then Support_Atomic_Primitives (P_Type));
+
+ begin
+ Rewrite (N, New_Occurrence_Of (V, Loc));
+
+ -- Analyze and resolve as boolean. Note that this attribute is a
+ -- static attribute in GNAT.
+
+ Analyze_And_Resolve (N, Standard_Boolean);
+ Static := True;
+ end Atomic_Always_Lock_Free;
+
---------
-- Bit --
---------
-- Lock_Free --
---------------
- -- Lock_Free attribute is a Boolean, thus no need to fold here.
+ when Attribute_Lock_Free => Lock_Free : declare
+ V : constant Entity_Id := Boolean_Literals (Uses_Lock_Free (P_Type));
- when Attribute_Lock_Free =>
- null;
+ begin
+ Rewrite (N, New_Occurrence_Of (V, Loc));
+
+ -- Analyze and resolve as boolean. Note that this attribute is a
+ -- static attribute in GNAT.
+
+ Analyze_And_Resolve (N, Standard_Boolean);
+ Static := True;
+ end Lock_Free;
----------
-- Last --
Id : constant Entity_Id := Entity (N);
Comp_Decl : Node_Id;
Comp_Id : Entity_Id := Empty;
- Comp_Size : Int := 0;
Comp_Type : Entity_Id;
begin
Layout_Type (Comp_Type);
- if Known_Static_Esize (Comp_Type) then
- Comp_Size := UI_To_Int (Esize (Comp_Type));
-
- -- If the Esize (Object_Size) is unknown at
- -- compile-time, look at the RM_Size
- -- (Value_Size) since it may have been set by
- -- an explicit representation clause.
-
- elsif Known_Static_RM_Size (Comp_Type) then
- Comp_Size :=
- UI_To_Int (RM_Size (Comp_Type));
-
- -- Worrisome missing else raise PE???
+ if not
+ Support_Atomic_Primitives (Comp_Type)
+ then
+ if Lock_Free_Given then
+ Error_Msg_NE
+ ("type of& must support atomic " &
+ "operations",
+ N, Comp_Id);
+ return Skip;
+ end if;
+
+ return Abandon;
end if;
-
- -- Check that the size of the component is 8,
- -- 16, 32 or 64 bits.
-
- -- What about AAMP here???
-
- case Comp_Size is
- when 8 | 16 | 32 | 64 =>
- null;
- when others =>
- if Lock_Free_Given then
- Error_Msg_NE
- ("type of& must support atomic " &
- "operations",
- N, Comp_Id);
- return Skip;
- end if;
-
- return Abandon;
- end case;
end if;
-- Check if another protected component has
end if;
end Subprogram_Access_Level;
+ -------------------------------
+ -- Support_Atomic_Primitives --
+ -------------------------------
+
+ function Support_Atomic_Primitives (Typ : Entity_Id) return Boolean is
+ Size : Int;
+
+ begin
+ -- Verify the alignment of Typ is known
+
+ if not Known_Alignment (Typ) then
+ return False;
+ end if;
+
+ if Known_Static_Esize (Typ) then
+ Size := UI_To_Int (Esize (Typ));
+
+ -- If the Esize (Object_Size) is unknown at compile-time, look at the
+ -- RM_Size (Value_Size) since it may have been set by an explicit rep
+ -- item.
+
+ elsif Known_Static_RM_Size (Typ) then
+ Size := UI_To_Int (RM_Size (Typ));
+
+ -- Otherwise, the size is considered to be unknown.
+
+ else
+ return False;
+ end if;
+
+ -- Check that the size of the component is 8, 16, 32 or 64 bits and that
+ -- Typ is properly aligned.
+
+ case Size is
+ when 8 | 16 | 32 | 64 =>
+ return Size = UI_To_Int (Alignment (Typ)) * 8;
+ when others =>
+ return False;
+ end case;
+ end Support_Atomic_Primitives;
+
-----------------
-- Trace_Scope --
-----------------
function Subprogram_Access_Level (Subp : Entity_Id) return Uint;
-- Return the accessibility level of the view denoted by Subp
+ function Support_Atomic_Primitives (Typ : Entity_Id) return Boolean;
+ -- Return True if Typ supports the GCC built-in atomic operations (i.e. if
+ -- Typ is properly sized and aligned).
+
procedure Trace_Scope (N : Node_Id; E : Entity_Id; Msg : String);
-- Print debugging information on entry to each unit being analyzed
Name_Asm_Input : constant Name_Id := N + $; -- GNAT
Name_Asm_Output : constant Name_Id := N + $; -- GNAT
Name_AST_Entry : constant Name_Id := N + $; -- VMS
+ Name_Atomic_Always_Lock_Free : constant Name_Id := N + $; -- GNAT
Name_Bit : constant Name_Id := N + $; -- GNAT
Name_Bit_Order : constant Name_Id := N + $;
Name_Bit_Position : constant Name_Id := N + $; -- GNAT
Attribute_Asm_Input,
Attribute_Asm_Output,
Attribute_AST_Entry,
+ Attribute_Atomic_Always_Lock_Free,
Attribute_Bit,
Attribute_Bit_Order,
Attribute_Bit_Position,
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := False;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := False;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := False;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := False;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := True;
Stack_Check_Limits : constant Boolean := False;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := False;
Stack_Check_Limits : constant Boolean := True;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := False;
Stack_Check_Limits : constant Boolean := True;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := False;
Stack_Check_Limits : constant Boolean := True;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := False;
Stack_Check_Limits : constant Boolean := True;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;
Stack_Check_Probes : constant Boolean := False;
Stack_Check_Limits : constant Boolean := True;
Support_Aggregates : constant Boolean := True;
- Support_Atomic_Primitives : constant Boolean := False;
Support_Composite_Assign : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts : constant Boolean := True;