-- overriding operation (see ARM12 6.6.1 (7)).
if Class_Present (N) then
- declare
+ Class_Wide_Condition : declare
T : constant Entity_Id := Find_Dispatching_Type (S);
ACW : Entity_Id := Empty;
procedure Replace_Type is new Traverse_Proc (Process);
+ -- Start of processing for Class_Wide_Condition
+
begin
+ if not Present (T) then
+ Error_Msg_Name_1 :=
+ Chars (Identifier (Corresponding_Aspect (N)));
+
+ Error_Msg_Name_2 := Name_Class;
+
+ Error_Msg_N
+ ("aspect `%''%` can only be specified for a primitive " &
+ "operation of a tagged type",
+ Corresponding_Aspect (N));
+ end if;
+
Replace_Type (Get_Pragma_Arg (Arg1));
- end;
+ end Class_Wide_Condition;
end if;
-- Remove the subprogram from the scope stack now that the pre-analysis
("aspect % requires ''Class for null procedure");
elsif not Nkind_In (PO, N_Subprogram_Declaration,
+ N_Expression_Function,
N_Generic_Subprogram_Declaration,
N_Entry_Declaration)
then
Set_Has_Delayed_Freeze (E);
end if;
- -- An interesting improvement here. If an object of type X is
- -- declared atomic, and the type X is not atomic, that's a
+ -- An interesting improvement here. If an object of composite
+ -- type X is declared atomic, and the type X isn't, that's a
-- pity, since it may not have appropriate alignment etc. We
-- can rescue this in the special case where the object and
-- type are in the same unit by just setting the type as
-- atomic, so that the back end will process it as atomic.
+ -- Note: we used to do this for elementary types as well,
+ -- but that turns out to be a bad idea and can have unwanted
+ -- effects, most notably if the type is elementary, the object
+ -- a simple component within a record, and both are in a spec:
+ -- every object of this type in the entire program will be
+ -- treated as atomic, thus incurring a potentially costly
+ -- synchronization operation for every access.
+
+ -- Of course it would be best if the back end could just adjust
+ -- the alignment etc for the specific object, but that's not
+ -- something we are capable of doing at this point.
+
Utyp := Underlying_Type (Etype (E));
if Present (Utyp)
+ and then Is_Composite_Type (Utyp)
and then Sloc (E) > No_Location
and then Sloc (Utyp) > No_Location
and then
Set_Has_Completion (Def_Id);
Set_Is_Constructor (Def_Id);
+ Set_Convention (Def_Id, Convention_CPP);
-- Imported C++ constructors are not dispatching primitives
-- because in C++ they don't have a dispatch table slot.
-- Follow subprogram renaming chain
Result := Def_Id;
- while Is_Subprogram (Result)
+
+ if Is_Subprogram (Result)
and then
Nkind (Parent (Declaration_Node (Result))) =
N_Subprogram_Renaming_Declaration
and then Present (Alias (Result))
- loop
+ then
Result := Alias (Result);
- end loop;
+ end if;
return Result;
end Get_Base_Subprogram;