Commit 551e1935 by Arnaud Charlet

[multiple changes]

2015-05-26  Gary Dismukes  <dismukes@adacore.com>

	* einfo.ads, sem_util.adb, sem_ch4.adb: Minor reformatting.

2015-05-26  Robert Dewar  <dewar@adacore.com>

	* exp_unst.adb, exp_unst.ads: Change to using Subps table index for
	making AREC entity names unique.

2015-05-26  Ed Schonberg  <schonberg@adacore.com>

	* sem_cat.adb (Has_Stream_Attribute_Definition): If the type
	has aspect specifications, examine the corresponding list of
	representation items to determine whether there is a visible
	stream operation. The attribute definition clause generated from
	the aspect will be inserted at the freeze point of the type,
	which may be in the private part and not directly visible,
	but the aspect makes the operation available to a client.

From-SVN: r223663
parent 07aa5e6f
2015-05-26 Gary Dismukes <dismukes@adacore.com>
* einfo.ads, sem_util.adb, sem_ch4.adb: Minor reformatting.
2015-05-26 Robert Dewar <dewar@adacore.com>
* exp_unst.adb, exp_unst.ads: Change to using Subps table index for
making AREC entity names unique.
2015-05-26 Ed Schonberg <schonberg@adacore.com>
* sem_cat.adb (Has_Stream_Attribute_Definition): If the type
has aspect specifications, examine the corresponding list of
representation items to determine whether there is a visible
stream operation. The attribute definition clause generated from
the aspect will be inserted at the freeze point of the type,
which may be in the private part and not directly visible,
but the aspect makes the operation available to a client.
2015-05-26 Robert Dewar <dewar@adacore.com> 2015-05-26 Robert Dewar <dewar@adacore.com>
* sem_util.adb: Minor code reorganization. * sem_util.adb: Minor code reorganization.
......
...@@ -1756,7 +1756,7 @@ package Einfo is ...@@ -1756,7 +1756,7 @@ package Einfo is
-- Object_Size clauses for a given entity. -- Object_Size clauses for a given entity.
-- Has_Out_Or_In_Out_Parameter (Flag110) -- Has_Out_Or_In_Out_Parameter (Flag110)
-- Present in subprograms, generic subprograms, entries and entry -- Present in subprograms, generic subprograms, entries, and entry
-- families. Set if they have at least one OUT or IN OUT parameter -- families. Set if they have at least one OUT or IN OUT parameter
-- (allowed for functions only in Ada 2012). -- (allowed for functions only in Ada 2012).
......
...@@ -124,8 +124,8 @@ package body Exp_Unst is ...@@ -124,8 +124,8 @@ package body Exp_Unst is
----------------------- -----------------------
procedure Unnest_Subprogram (Subp : Entity_Id; Subp_Body : Node_Id) is procedure Unnest_Subprogram (Subp : Entity_Id; Subp_Body : Node_Id) is
function AREC_String (Lev : Pos) return String; function AREC_Name (J : Pos; S : String) return Name_Id;
-- Given a level value, 1, 2, ... returns the string AREC, AREC2, ... -- Returns name for string ARECjS, where j is the decimal value of j
function Enclosing_Subp (Subp : SI_Type) return SI_Type; function Enclosing_Subp (Subp : SI_Type) return SI_Type;
-- Subp is the index of a subprogram which has a Lev greater than 1. -- Subp is the index of a subprogram which has a Lev greater than 1.
...@@ -137,34 +137,32 @@ package body Exp_Unst is ...@@ -137,34 +137,32 @@ package body Exp_Unst is
-- function returns the level of nesting (Subp = 1, subprograms that -- function returns the level of nesting (Subp = 1, subprograms that
-- are immediately nested within Subp = 2, etc). -- are immediately nested within Subp = 2, etc).
function Img_Pos (N : Pos) return String;
-- Return image of N without leading blank
function Subp_Index (Sub : Entity_Id) return SI_Type; function Subp_Index (Sub : Entity_Id) return SI_Type;
-- Given the entity for a subprogram, return corresponding Subps index -- Given the entity for a subprogram, return corresponding Subps index
function Suffixed_Name (Ent : Entity_Id) return Name_Id; function Upref_Name
-- Given an entity Ent, return its name (Char (Ent)) suffixed with (Ent : Entity_Id;
-- two underscores and the entity number, to ensure a unique name. Index : Pos;
Clist : List_Id) return Name_Id;
function Upref_Name (Ent : Entity_Id; Clist : List_Id) return Name_Id;
-- This function returns the name to be used in the activation record to -- This function returns the name to be used in the activation record to
-- reference the variable uplevel. Clist is the list of components that -- reference the variable uplevel. Clist is the list of components that
-- have been created in the activation record so far. Normally this is -- have been created in the activation record so far. Normally the name
-- just a copy of the Chars field of the entity. The exception is when -- is just a copy of the Chars field of the entity. The exception is
-- the name has already been used, in which case we suffix the name with -- when the name has already been used, in which case we suffix the name
-- the entity number to avoid duplication. This happens with declare -- with the index value Index to avoid duplication. This happens with
-- blocks and generic parameters at least. -- declare blocks and generic parameters at least.
----------------- ---------------
-- AREC_String -- -- AREC_Name --
----------------- ---------------
function AREC_String (Lev : Pos) return String is function AREC_Name (J : Pos; S : String) return Name_Id is
begin begin
if Lev > 9 then return Name_Find_Str ("AREC" & Img_Pos (J) & S);
return AREC_String (Lev / 10) & Character'Val (Lev mod 10 + 48); end AREC_Name;
else
return "AREC" & Character'Val (Lev + 48);
end if;
end AREC_String;
-------------------- --------------------
-- Enclosing_Subp -- -- Enclosing_Subp --
...@@ -199,6 +197,27 @@ package body Exp_Unst is ...@@ -199,6 +197,27 @@ package body Exp_Unst is
end loop; end loop;
end Get_Level; end Get_Level;
-------------
-- Img_Pos --
-------------
function Img_Pos (N : Pos) return String is
Buf : String (1 .. 20);
Ptr : Natural;
NV : Nat;
begin
Ptr := Buf'Last;
NV := N;
while NV /= 0 loop
Buf (Ptr) := Character'Val (48 + NV mod 10);
Ptr := Ptr - 1;
NV := NV / 10;
end loop;
return Buf (Ptr + 1 .. Buf'Last);
end Img_Pos;
---------------- ----------------
-- Subp_Index -- -- Subp_Index --
---------------- ----------------
...@@ -209,23 +228,15 @@ package body Exp_Unst is ...@@ -209,23 +228,15 @@ package body Exp_Unst is
return SI_Type (UI_To_Int (Subps_Index (Sub))); return SI_Type (UI_To_Int (Subps_Index (Sub)));
end Subp_Index; end Subp_Index;
-------------------
-- Suffixed_Name --
-------------------
function Suffixed_Name (Ent : Entity_Id) return Name_Id is
begin
Get_Name_String (Chars (Ent));
Add_Str_To_Name_Buffer ("__");
Add_Nat_To_Name_Buffer (Nat (Ent));
return Name_Enter;
end Suffixed_Name;
---------------- ----------------
-- Upref_Name -- -- Upref_Name --
---------------- ----------------
function Upref_Name (Ent : Entity_Id; Clist : List_Id) return Name_Id is function Upref_Name
(Ent : Entity_Id;
Index : Pos;
Clist : List_Id) return Name_Id
is
C : Node_Id; C : Node_Id;
begin begin
C := First (Clist); C := First (Clist);
...@@ -233,7 +244,8 @@ package body Exp_Unst is ...@@ -233,7 +244,8 @@ package body Exp_Unst is
if No (C) then if No (C) then
return Chars (Ent); return Chars (Ent);
elsif Chars (Defining_Identifier (C)) = Chars (Ent) then elsif Chars (Defining_Identifier (C)) = Chars (Ent) then
return Suffixed_Name (Ent); return Name_Find_Str
(Get_Name_String (Chars (Ent)) & Img_Pos (Index));
else else
Next (C); Next (C);
end if; end if;
...@@ -946,7 +958,6 @@ package body Exp_Unst is ...@@ -946,7 +958,6 @@ package body Exp_Unst is
declare declare
STJ : Subp_Entry renames Subps.Table (J); STJ : Subp_Entry renames Subps.Table (J);
Loc : constant Source_Ptr := Sloc (STJ.Bod); Loc : constant Source_Ptr := Sloc (STJ.Bod);
ARS : constant String := AREC_String (STJ.Lev);
begin begin
-- First we create the ARECnF entity for the additional formal for -- First we create the ARECnF entity for the additional formal for
...@@ -954,32 +965,26 @@ package body Exp_Unst is ...@@ -954,32 +965,26 @@ package body Exp_Unst is
if STJ.Uplevel_Ref < STJ.Lev then if STJ.Uplevel_Ref < STJ.Lev then
STJ.ARECnF := STJ.ARECnF :=
Make_Defining_Identifier (Loc, Make_Defining_Identifier (Loc, Chars => AREC_Name (J, "F"));
Chars => Name_Find_Str (AREC_String (STJ.Lev - 1) & "F"));
end if; end if;
-- Define the AREC entities for the activation record if needed -- Define the AREC entities for the activation record if needed
if STJ.Declares_AREC then if STJ.Declares_AREC then
STJ.ARECn := STJ.ARECn :=
Make_Defining_Identifier (Loc, Name_Find_Str (ARS)); Make_Defining_Identifier (Loc, AREC_Name (J, ""));
STJ.ARECnT := STJ.ARECnT :=
Make_Defining_Identifier (Loc, Name_Find_Str (ARS & "T")); Make_Defining_Identifier (Loc, AREC_Name (J, "T"));
STJ.ARECnPT := STJ.ARECnPT :=
Make_Defining_Identifier (Loc, Name_Find_Str (ARS & "PT")); Make_Defining_Identifier (Loc, AREC_Name (J, "PT"));
STJ.ARECnP := STJ.ARECnP :=
Make_Defining_Identifier (Loc, Name_Find_Str (ARS & "P")); Make_Defining_Identifier (Loc, AREC_Name (J, "P"));
-- Define uplink component entity if inner nesting case -- Define uplink component entity if inner nesting case
if Present (STJ.ARECnF) then if Present (STJ.ARECnF) then
declare STJ.ARECnU :=
ARS1 : constant String := AREC_String (STJ.Lev - 1); Make_Defining_Identifier (Loc, AREC_Name (J, "U"));
begin
STJ.ARECnU :=
Make_Defining_Identifier (Loc,
Chars => Name_Find_Str (ARS1 & "U"));
end;
end if; end if;
end if; end if;
end; end;
...@@ -1103,22 +1108,15 @@ package body Exp_Unst is ...@@ -1103,22 +1108,15 @@ package body Exp_Unst is
-- List of new declarations we create -- List of new declarations we create
begin begin
-- Suffix the ARECnT and ARECnPT names to make sure that
-- they are unique when Cprint moves the declarations to
-- the outer level.
Set_Chars (STJ.ARECnT, Suffixed_Name (STJ.ARECnT));
Set_Chars (STJ.ARECnPT, Suffixed_Name (STJ.ARECnPT));
-- Build list of component declarations for ARECnT -- Build list of component declarations for ARECnT
Clist := Empty_List; Clist := Empty_List;
-- If we are in a subprogram that has a static link that -- If we are in a subprogram that has a static link that
-- is passed in (as indicated by ARECnF being defined), -- is passed in (as indicated by ARECnF being defined),
-- then include ARECnU : ARECmPT where m is one less than -- then include ARECnU : ARECmPT where ARECmPT comes from
-- the current level and the entity ARECnPT comes from -- the level one higher than the current level, and the
-- the enclosing subprogram. -- entity ARECnPT comes from the enclosing subprogram.
if Present (STJ.ARECnF) then if Present (STJ.ARECnF) then
declare declare
...@@ -1142,14 +1140,20 @@ package body Exp_Unst is ...@@ -1142,14 +1140,20 @@ package body Exp_Unst is
Elmt : Elmt_Id; Elmt : Elmt_Id;
Uent : Entity_Id; Uent : Entity_Id;
Indx : Nat;
-- 1's origin of index in list of elements. This is
-- used to uniquify names if needed in Upref_Name.
begin begin
Elmt := First_Elmt (STJ.Uents); Elmt := First_Elmt (STJ.Uents);
Indx := 0;
while Present (Elmt) loop while Present (Elmt) loop
Uent := Node (Elmt); Uent := Node (Elmt);
Indx := Indx + 1;
Comp := Comp :=
Make_Defining_Identifier (Loc, Make_Defining_Identifier (Loc,
Chars => Upref_Name (Uent, Clist)); Chars => Upref_Name (Uent, Indx, Clist));
Set_Activation_Record_Component Set_Activation_Record_Component
(Uent, Comp); (Uent, Comp);
......
...@@ -184,9 +184,9 @@ package Exp_Unst is ...@@ -184,9 +184,9 @@ package Exp_Unst is
-- The fields of AREC1 are set at the point the corresponding entity -- The fields of AREC1 are set at the point the corresponding entity
-- is declared (immediately for parameters). -- is declared (immediately for parameters).
-- Note: the 1 in all these names represents the fact that we are at the -- Note: the 1 in all these names is a unique index number. Different
-- outer level of nesting. As we will see later, deeper levels of nesting -- scopes requiring different ARECnT declarations will have different
-- will use AREC2, AREC3, ... -- values of n to ensure uniqueness.
-- Note: normally the field names in the activation record match the -- Note: normally the field names in the activation record match the
-- name of the entity. An exception is when the entity is declared in -- name of the entity. An exception is when the entity is declared in
...@@ -294,8 +294,8 @@ package Exp_Unst is ...@@ -294,8 +294,8 @@ package Exp_Unst is
-- What we do is to always generate a local constant for any dynamic -- What we do is to always generate a local constant for any dynamic
-- bound in a dynamic subtype xx with name xx_FIRST or xx_LAST. The one -- bound in a dynamic subtype xx with name xx_FIRST or xx_LAST. The one
-- case where we can skip this is where the bound is For -- case where we can skip this is where the bound is e.g. in the third
-- example in the third example above, subtype dynam is expanded as -- example above, subtype dynam is expanded as
-- dynam_LAST : constant Integer := y + 3; -- dynam_LAST : constant Integer := y + 3;
-- subtype dynam is integer range x .. dynam_LAST; -- subtype dynam is integer range x .. dynam_LAST;
...@@ -465,8 +465,8 @@ package Exp_Unst is ...@@ -465,8 +465,8 @@ package Exp_Unst is
-- return inner1 (x, AREC1P); -- return inner1 (x, AREC1P);
-- end case4x; -- end case4x;
-- As can be seen in this example, the level number following AREC in the -- As can be seen in this example, the index numbers following AREC in the
-- names avoids any confusion between AREC names at different levels. -- generated names avoid confusion between AREC names at different levels.
------------------------- -------------------------
-- Name Disambiguation -- -- Name Disambiguation --
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- B o d y -- -- B o d y --
-- -- -- --
-- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- Copyright (C) 1992-2015, Free Software Foundation, Inc. --
-- -- -- --
-- GNAT is free software; you can redistribute it and/or modify it under -- -- 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- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -441,20 +441,15 @@ package body Sem_Cat is ...@@ -441,20 +441,15 @@ package body Sem_Cat is
At_Any_Place : Boolean := False) return Boolean At_Any_Place : Boolean := False) return Boolean
is is
Rep_Item : Node_Id; Rep_Item : Node_Id;
Full_Type : Entity_Id := Typ; Real_Rep : Node_Id;
-- The stream operation may be specified by an attribute definition
-- clause in the source, or by an aspect that generates such an
-- attribute definition. For an aspect, the generated attribute
-- definition may be placed at the freeze point of the full view of
-- the type, but the aspect specification makes the operation visible
-- to a client wherever the partial view is visible.
begin begin
-- In the case of a type derived from a private view, any specified
-- stream attributes will be attached to the derived type's underlying
-- type rather the derived type entity itself (which is itself private).
if Is_Private_Type (Typ)
and then Is_Derived_Type (Typ)
and then Present (Full_View (Typ))
then
Full_Type := Underlying_Type (Typ);
end if;
-- We start from the declaration node and then loop until the end of -- We start from the declaration node and then loop until the end of
-- the list until we find the requested attribute definition clause. -- the list until we find the requested attribute definition clause.
-- In Ada 2005 mode, clauses are ignored if they are not currently -- In Ada 2005 mode, clauses are ignored if they are not currently
...@@ -462,10 +457,19 @@ package body Sem_Cat is ...@@ -462,10 +457,19 @@ package body Sem_Cat is
-- inserted by the expander at the point where the clause occurs), -- inserted by the expander at the point where the clause occurs),
-- unless At_Any_Place is true. -- unless At_Any_Place is true.
Rep_Item := First_Rep_Item (Full_Type); Rep_Item := First_Rep_Item (Typ);
while Present (Rep_Item) loop while Present (Rep_Item) loop
if Nkind (Rep_Item) = N_Attribute_Definition_Clause then Real_Rep := Rep_Item;
case Chars (Rep_Item) is
-- If the representation item is an aspect specification, retrieve
-- the corresponding pragma or attribute definition.
if Nkind (Rep_Item) = N_Aspect_Specification then
Real_Rep := Aspect_Rep_Item (Rep_Item);
end if;
if Nkind (Real_Rep) = N_Attribute_Definition_Clause then
case Chars (Real_Rep) is
when Name_Read => when Name_Read =>
exit when Nam = TSS_Stream_Read; exit when Nam = TSS_Stream_Read;
...@@ -487,14 +491,29 @@ package body Sem_Cat is ...@@ -487,14 +491,29 @@ package body Sem_Cat is
Next_Rep_Item (Rep_Item); Next_Rep_Item (Rep_Item);
end loop; end loop;
-- If At_Any_Place is true, return True if the attribute is available -- If not found, and the type is derived from a private view, check
-- at any place; if it is false, return True only if the attribute is -- for a stream attribute inherited from parent. Any specified stream
-- currently visible. -- attributes will be attached to the derived type's underlying type
-- rather the derived type entity itself (which is itself private).
if No (Rep_Item)
and then Is_Private_Type (Typ)
and then Is_Derived_Type (Typ)
and then Present (Full_View (Typ))
then
return Has_Stream_Attribute_Definition
(Underlying_Type (Typ), Nam, At_Any_Place);
-- Otherwise, if At_Any_Place is true, return True if the attribute is
-- available at any place; if it is false, return True only if the
-- attribute is currently visible.
return Present (Rep_Item) else
and then (Ada_Version < Ada_2005 return Present (Rep_Item)
or else At_Any_Place and then (Ada_Version < Ada_2005
or else not Is_Hidden (Entity (Rep_Item))); or else At_Any_Place
or else not Is_Hidden (Entity (Rep_Item)));
end if;
end Has_Stream_Attribute_Definition; end Has_Stream_Attribute_Definition;
---------------------------- ----------------------------
......
...@@ -916,30 +916,30 @@ package body Sem_Ch4 is ...@@ -916,30 +916,30 @@ package body Sem_Ch4 is
---------------------------- ----------------------------
-- The identification of conflicts in calls to functions with writable -- The identification of conflicts in calls to functions with writable
-- actuals is performed in the analysis phase of the frontend to ensure -- actuals is performed in the analysis phase of the front end to ensure
-- that it reports exactly the same errors compiling with and without -- that it reports exactly the same errors compiling with and without
-- expansion enabled. It is performed in two stages: -- expansion enabled. It is performed in two stages:
-- 1) When a call to a function with out-mode parameters is found -- 1) When a call to a function with out-mode parameters is found,
-- we climb to the outermost enclosing construct which can be -- we climb to the outermost enclosing construct that can be
-- evaluated in arbitrary order and we mark it with the flag -- evaluated in arbitrary order and we mark it with the flag
-- Check_Actuals. -- Check_Actuals.
-- 2) When the analysis of the marked node is complete then we -- 2) When the analysis of the marked node is complete, we traverse
-- traverse its decorated subtree searching for conflicts -- its decorated subtree searching for conflicts (see function
-- (see function Sem_Util.Check_Function_Writable_Actuals). -- Sem_Util.Check_Function_Writable_Actuals).
-- The unique exception to this general rule are aggregates, since -- The unique exception to this general rule is for aggregates, since
-- their analysis is performed by the frontend in the resolution -- their analysis is performed by the front end in the resolution
-- phase. For aggregates we do not climb to its enclosing construct: -- phase. For aggregates we do not climb to their enclosing construct:
-- we restrict the analysis to the subexpressions initializing the -- we restrict the analysis to the subexpressions initializing the
-- aggregate components. -- aggregate components.
-- This implies that the analysis of expressions containing aggregates -- This implies that the analysis of expressions containing aggregates
-- is not complete since there may be conflicts on writable actuals -- is not complete, since there may be conflicts on writable actuals
-- involving subexpressions of the enclosing logical or arithmetic -- involving subexpressions of the enclosing logical or arithmetic
-- expressions. However, we cannot wait and perform the analysis when -- expressions. However, we cannot wait and perform the analysis when
-- the whole subtree is resolved since the subtrees may be transformed -- the whole subtree is resolved, since the subtrees may be transformed,
-- thus adding extra complexity and computation cost to identify and -- thus adding extra complexity and computation cost to identify and
-- report exactly the same errors compiling with and without expansion -- report exactly the same errors compiling with and without expansion
-- enabled. -- enabled.
...@@ -948,9 +948,9 @@ package body Sem_Ch4 is ...@@ -948,9 +948,9 @@ package body Sem_Ch4 is
function Is_Arbitrary_Evaluation_Order_Construct function Is_Arbitrary_Evaluation_Order_Construct
(N : Node_Id) return Boolean; (N : Node_Id) return Boolean;
-- Return True if N is an Ada construct which may evaluate in -- Return True if N is an Ada construct which may be evaluated in
-- arbitrary order. This function does not cover all the language -- an arbitrary order. This function does not cover all the language
-- constructs which can be evaluated in arbitrary order but the -- constructs that can be evaluated in arbitrary order, but only the
-- subset needed for AI05-0144. -- subset needed for AI05-0144.
--------------------------------------------- ---------------------------------------------
...@@ -1003,11 +1003,11 @@ package body Sem_Ch4 is ...@@ -1003,11 +1003,11 @@ package body Sem_Ch4 is
begin begin
while Present (P) loop while Present (P) loop
-- For object declarations we can climb to such node from -- For object declarations we can climb to the node from
-- its object definition branch or from its initializing -- its object definition branch or from its initializing
-- expression. We prefer to mark the child node as the -- expression. We prefer to mark the child node as the
-- outermost construct to avoid adding further complexity -- outermost construct to avoid adding further complexity
-- to the routine which will take care later of -- to the routine that will later take care of
-- performing the writable actuals check. -- performing the writable actuals check.
if Is_Arbitrary_Evaluation_Order_Construct (P) if Is_Arbitrary_Evaluation_Order_Construct (P)
...@@ -1407,8 +1407,8 @@ package body Sem_Ch4 is ...@@ -1407,8 +1407,8 @@ package body Sem_Ch4 is
Check_Writable_Actuals (N); Check_Writable_Actuals (N);
-- If found and the outermost construct which can be evaluated in -- If found and the outermost construct that can be evaluated in
-- arbitrary order is precisely this call then check all its -- an arbitrary order is precisely this call, then check all its
-- actuals. -- actuals.
if Check_Actuals (N) then if Check_Actuals (N) then
......
...@@ -2119,10 +2119,10 @@ package body Sem_Util is ...@@ -2119,10 +2119,10 @@ package body Sem_Util is
then then
return Skip; return Skip;
-- For now we skip aggregate discriminants since they require -- For now we skip aggregate discriminants, since they require
-- performing the analysis in two phases to identify conflicts: -- performing the analysis in two phases to identify conflicts:
-- first one analyzing discriminants and second one analyzing -- first one analyzing discriminants and second one analyzing
-- the rest of components (since at runtime discriminants are -- the rest of components (since at run time, discriminants are
-- evaluated prior to components): too much computation cost -- evaluated prior to components): too much computation cost
-- to identify a corner case??? -- to identify a corner case???
...@@ -2191,8 +2191,8 @@ package body Sem_Util is ...@@ -2191,8 +2191,8 @@ package body Sem_Util is
-- Report the error on the second occurrence of the -- Report the error on the second occurrence of the
-- identifier. We cannot assume that N is the second -- identifier. We cannot assume that N is the second
-- occurrence since traverse_func walks through Field2 -- occurrence, since Traverse_Func walks through Field2
-- last (see comment in the body of traverse_func). -- last (see comment in the body of Traverse_Func).
declare declare
Elmt : Elmt_Id; Elmt : Elmt_Id;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment