This patch renames Next and Previous in a-convec.ads and other
containers to be _Next and _Previous, to avoid namespace pollution. The
compiler now uses the leading-underscore names to look them up.
The scanner is changed to allow this.
Tested on x86_64-pc-linux-gnu, committed on trunk
gcc/ada/
* exp_ch5.adb (Expand_Iterator_Loop_Over_Array): Use _Next and
_Previous in the optimized expansion of "for ... of". No longer
need to check parameter profiles for these, because the
leading-underscore names are unique.
* libgnat/a-convec.ads (_Next, _Previous): Renamings of Next and
Previous, to avoid namespace pollution.
* libgnat/a-cbdlli.ads, libgnat/a-cbhama.ads,
libgnat/a-cbhase.ads, libgnat/a-cbmutr.ads,
libgnat/a-cborma.ads, libgnat/a-cborse.ads,
libgnat/a-cdlili.ads, libgnat/a-cidlli.ads,
libgnat/a-cihama.ads, libgnat/a-cihase.ads,
libgnat/a-cimutr.ads, libgnat/a-ciorma.ads,
libgnat/a-ciorse.ads, libgnat/a-cobove.ads,
libgnat/a-cohama.ads, libgnat/a-cohase.ads,
libgnat/a-coinve.ads, libgnat/a-comutr.ads,
libgnat/a-coorma.ads, libgnat/a-coorse.ads: Likewise. Also,
remove duplicated comments -- refer to one comment about _Next,
_Previous, Pseudo_Reference in libgnat/a-convec.ads. DRY.
* scng.adb (Scan): Allow leading underscores in identifiers in
the run-time library.
* snames.ads-tmpl (Name_uNext, Name_uPrevious): New names with
leading underscores.
diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -4924,7 +4924,8 @@ package body Exp_Ch5 is
-- In the optimized case, we make use of these:
- -- procedure Next (Position : in out Cursor); -- instead of Iter.Next
+ -- procedure _Next (Position : in out Cursor); -- instead of Iter.Next
+ -- (or _Previous for reverse loops)
-- function Pseudo_Reference
-- (Container : aliased Vector'Class) return Reference_Control_Type;
@@ -4939,6 +4940,11 @@ package body Exp_Ch5 is
-- pollute the namespace for clients. The compiler has no trouble breaking
-- privacy to call things in the private part of an instance.)
+ -- Note that Next and Previous are renamed as _Next and _Previous with
+ -- leading underscores. Leading underscores are illegal in Ada, but we
+ -- allow them in the run-time library. This allows us to avoid polluting
+ -- the user-visible namespaces.
+
-- Source:
-- for X of My_Vector loop
@@ -4989,7 +4995,7 @@ package body Exp_Ch5 is
-- X.Count := X.Count + 1;
-- ...
--
- -- Next (Cur); -- or Prev
+ -- _Next (Cur); -- or _Previous
-- -- This is instead of "Cur := Next (Iter, Cur);"
-- end;
-- -- No finalization here
@@ -5015,13 +5021,14 @@ package body Exp_Ch5 is
Stats : List_Id := Statements (N);
-- Maybe wrapped in a conditional if a filter is present
- Cursor : Entity_Id;
- Decl : Node_Id;
- Iter_Type : Entity_Id;
- Iterator : Entity_Id;
- Name_Init : Name_Id;
- Name_Step : Name_Id;
- New_Loop : Node_Id;
+ Cursor : Entity_Id;
+ Decl : Node_Id;
+ Iter_Type : Entity_Id;
+ Iterator : Entity_Id;
+ Name_Init : Name_Id;
+ Name_Step : Name_Id;
+ Name_Fast_Step : Name_Id;
+ New_Loop : Node_Id;
Fast_Element_Access_Op : Entity_Id := Empty;
Fast_Step_Op : Entity_Id := Empty;
@@ -5049,9 +5056,11 @@ package body Exp_Ch5 is
if Reverse_Present (I_Spec) then
Name_Init := Name_Last;
Name_Step := Name_Previous;
+ Name_Fast_Step := Name_uPrevious;
else
Name_Init := Name_First;
Name_Step := Name_Next;
+ Name_Fast_Step := Name_uNext;
end if;
-- The type of the iterator is the return type of the Iterate function
@@ -5189,14 +5198,13 @@ package body Exp_Ch5 is
Iter_Pack := Scope (Root_Type (Etype (Iter_Type)));
- -- Find declarations needed for "for ... of" optimization
+ -- Find declarations needed for "for ... of" optimization.
-- These declarations come from GNAT sources or sources
-- derived from them. User code may include additional
-- overloadings with similar names, and we need to perforn
-- some reasonable resolution to find the needed primitives.
- -- It is unclear whether this mechanism is fragile if a user
- -- makes arbitrary changes to the private part of a package
- -- that supports iterators.
+ -- Note that we use _Next or _Previous to avoid picking up
+ -- some arbitrary user-defined Next or Previous.
Ent := First_Entity (Pack);
while Present (Ent) loop
@@ -5215,12 +5223,7 @@ package body Exp_Ch5 is
-- Next or Prev procedure with one parameter called
-- Position.
- elsif Chars (Ent) = Name_Step
- and then Ekind (Ent) = E_Procedure
- and then Present (First_Formal (Ent))
- and then Chars (First_Formal (Ent)) = Name_Position
- and then No (Next_Formal (First_Formal (Ent)))
- then
+ elsif Chars (Ent) = Name_Fast_Step then
pragma Assert (No (Fast_Step_Op));
Fast_Step_Op := Ent;
diff --git a/gcc/ada/libgnat/a-cbdlli.ads b/gcc/ada/libgnat/a-cbdlli.ads
--- a/gcc/ada/libgnat/a-cbdlli.ads
+++ b/gcc/ada/libgnat/a-cbdlli.ads
@@ -364,10 +364,10 @@ private
for Reference_Type'Read use Read;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Exp_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
+
+ procedure _Next (Position : in out Cursor) renames Next;
+ procedure _Previous (Position : in out Cursor) renames Previous;
function Pseudo_Reference
(Container : aliased List'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-cbhama.ads b/gcc/ada/libgnat/a-cbhama.ads
--- a/gcc/ada/libgnat/a-cbhama.ads
+++ b/gcc/ada/libgnat/a-cbhama.ads
@@ -439,10 +439,9 @@ private
for Reference_Type'Read use Read;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Sem_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
+
+ procedure _Next (Position : in out Cursor) renames Next;
function Pseudo_Reference
(Container : aliased Map'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-cbhase.ads b/gcc/ada/libgnat/a-cbhase.ads
--- a/gcc/ada/libgnat/a-cbhase.ads
+++ b/gcc/ada/libgnat/a-cbhase.ads
@@ -596,10 +596,9 @@ private
for Constant_Reference_Type'Write use Write;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Sem_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
+
+ procedure _Next (Position : in out Cursor) renames Next;
function Pseudo_Reference
(Container : aliased Set'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-cbmutr.ads b/gcc/ada/libgnat/a-cbmutr.ads
--- a/gcc/ada/libgnat/a-cbmutr.ads
+++ b/gcc/ada/libgnat/a-cbmutr.ads
@@ -386,10 +386,7 @@ private
Item : out Reference_Type);
for Reference_Type'Read use Read;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Exp_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
function Pseudo_Reference
(Container : aliased Tree'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-cborma.ads b/gcc/ada/libgnat/a-cborma.ads
--- a/gcc/ada/libgnat/a-cborma.ads
+++ b/gcc/ada/libgnat/a-cborma.ads
@@ -341,10 +341,10 @@ private
for Reference_Type'Write use Write;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Sem_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
+
+ procedure _Next (Position : in out Cursor) renames Next;
+ procedure _Previous (Position : in out Cursor) renames Previous;
function Pseudo_Reference
(Container : aliased Map'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-cborse.ads b/gcc/ada/libgnat/a-cborse.ads
--- a/gcc/ada/libgnat/a-cborse.ads
+++ b/gcc/ada/libgnat/a-cborse.ads
@@ -435,10 +435,10 @@ private
for Constant_Reference_Type'Write use Write;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Sem_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
+
+ procedure _Next (Position : in out Cursor) renames Next;
+ procedure _Previous (Position : in out Cursor) renames Previous;
function Pseudo_Reference
(Container : aliased Set'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-cdlili.ads b/gcc/ada/libgnat/a-cdlili.ads
--- a/gcc/ada/libgnat/a-cdlili.ads
+++ b/gcc/ada/libgnat/a-cdlili.ads
@@ -374,10 +374,10 @@ private
for Reference_Type'Read use Read;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Sem_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
+
+ procedure _Next (Position : in out Cursor) renames Next;
+ procedure _Previous (Position : in out Cursor) renames Previous;
function Pseudo_Reference
(Container : aliased List'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-cidlli.ads b/gcc/ada/libgnat/a-cidlli.ads
--- a/gcc/ada/libgnat/a-cidlli.ads
+++ b/gcc/ada/libgnat/a-cidlli.ads
@@ -368,10 +368,10 @@ private
for Reference_Type'Read use Read;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Exp_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
+
+ procedure _Next (Position : in out Cursor) renames Next;
+ procedure _Previous (Position : in out Cursor) renames Previous;
function Pseudo_Reference
(Container : aliased List'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-cihama.ads b/gcc/ada/libgnat/a-cihama.ads
--- a/gcc/ada/libgnat/a-cihama.ads
+++ b/gcc/ada/libgnat/a-cihama.ads
@@ -440,10 +440,9 @@ private
for Reference_Type'Read use Read;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Sem_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
+
+ procedure _Next (Position : in out Cursor) renames Next;
function Pseudo_Reference
(Container : aliased Map'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-cihase.ads b/gcc/ada/libgnat/a-cihase.ads
--- a/gcc/ada/libgnat/a-cihase.ads
+++ b/gcc/ada/libgnat/a-cihase.ads
@@ -589,10 +589,9 @@ private
for Constant_Reference_Type'Write use Write;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Sem_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
+
+ procedure _Next (Position : in out Cursor) renames Next;
function Pseudo_Reference
(Container : aliased Set'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-cimutr.ads b/gcc/ada/libgnat/a-cimutr.ads
--- a/gcc/ada/libgnat/a-cimutr.ads
+++ b/gcc/ada/libgnat/a-cimutr.ads
@@ -439,10 +439,7 @@ private
for Reference_Type'Write use Write;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Exp_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
function Pseudo_Reference
(Container : aliased Tree'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-ciorma.ads b/gcc/ada/libgnat/a-ciorma.ads
--- a/gcc/ada/libgnat/a-ciorma.ads
+++ b/gcc/ada/libgnat/a-ciorma.ads
@@ -355,10 +355,10 @@ private
for Reference_Type'Write use Write;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Sem_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
+
+ procedure _Next (Position : in out Cursor) renames Next;
+ procedure _Previous (Position : in out Cursor) renames Previous;
function Pseudo_Reference
(Container : aliased Map'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-ciorse.ads b/gcc/ada/libgnat/a-ciorse.ads
--- a/gcc/ada/libgnat/a-ciorse.ads
+++ b/gcc/ada/libgnat/a-ciorse.ads
@@ -454,10 +454,10 @@ private
for Constant_Reference_Type'Write use Write;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Sem_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
+
+ procedure _Next (Position : in out Cursor) renames Next;
+ procedure _Previous (Position : in out Cursor) renames Previous;
function Pseudo_Reference
(Container : aliased Set'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-cobove.ads b/gcc/ada/libgnat/a-cobove.ads
--- a/gcc/ada/libgnat/a-cobove.ads
+++ b/gcc/ada/libgnat/a-cobove.ads
@@ -511,10 +511,10 @@ private
for Reference_Type'Write use Write;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Exp_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
+
+ procedure _Next (Position : in out Cursor) renames Next;
+ procedure _Previous (Position : in out Cursor) renames Previous;
function Pseudo_Reference
(Container : aliased Vector'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-cohama.ads b/gcc/ada/libgnat/a-cohama.ads
--- a/gcc/ada/libgnat/a-cohama.ads
+++ b/gcc/ada/libgnat/a-cohama.ads
@@ -543,10 +543,9 @@ private
for Reference_Type'Read use Read;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Sem_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
+
+ procedure _Next (Position : in out Cursor) renames Next;
function Pseudo_Reference
(Container : aliased Map'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-cohase.ads b/gcc/ada/libgnat/a-cohase.ads
--- a/gcc/ada/libgnat/a-cohase.ads
+++ b/gcc/ada/libgnat/a-cohase.ads
@@ -623,10 +623,9 @@ private
for Constant_Reference_Type'Write use Write;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Sem_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
+
+ procedure _Next (Position : in out Cursor) renames Next;
function Pseudo_Reference
(Container : aliased Set'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-coinve.ads b/gcc/ada/libgnat/a-coinve.ads
--- a/gcc/ada/libgnat/a-coinve.ads
+++ b/gcc/ada/libgnat/a-coinve.ads
@@ -512,10 +512,10 @@ private
for Reference_Type'Read use Read;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Exp_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
+
+ procedure _Next (Position : in out Cursor) renames Next;
+ procedure _Previous (Position : in out Cursor) renames Previous;
function Pseudo_Reference
(Container : aliased Vector'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-comutr.ads b/gcc/ada/libgnat/a-comutr.ads
--- a/gcc/ada/libgnat/a-comutr.ads
+++ b/gcc/ada/libgnat/a-comutr.ads
@@ -491,10 +491,7 @@ private
for Reference_Type'Write use Write;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Exp_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
function Pseudo_Reference
(Container : aliased Tree'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-convec.ads b/gcc/ada/libgnat/a-convec.ads
--- a/gcc/ada/libgnat/a-convec.ads
+++ b/gcc/ada/libgnat/a-convec.ads
@@ -829,10 +829,13 @@ private
for Reference_Type'Read use Read;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Exp_Ch5 for
- -- details.
+ -- Three operations are used to optimize the expansion of "for ... of"
+ -- loops: the Next(Cursor) (or Previous) procedure in the visible part,
+ -- and the following Pseudo_Reference and Get_Element_Access functions.
+ -- See Exp_Ch5 for details, including the leading underscores here.
+
+ procedure _Next (Position : in out Cursor) renames Next;
+ procedure _Previous (Position : in out Cursor) renames Previous;
function Pseudo_Reference
(Container : aliased Vector'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-coorma.ads b/gcc/ada/libgnat/a-coorma.ads
--- a/gcc/ada/libgnat/a-coorma.ads
+++ b/gcc/ada/libgnat/a-coorma.ads
@@ -357,10 +357,10 @@ private
for Reference_Type'Write use Write;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Sem_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
+
+ procedure _Next (Position : in out Cursor) renames Next;
+ procedure _Previous (Position : in out Cursor) renames Previous;
function Pseudo_Reference
(Container : aliased Map'Class) return Reference_Control_Type;
diff --git a/gcc/ada/libgnat/a-coorse.ads b/gcc/ada/libgnat/a-coorse.ads
--- a/gcc/ada/libgnat/a-coorse.ads
+++ b/gcc/ada/libgnat/a-coorse.ads
@@ -437,10 +437,10 @@ private
for Constant_Reference_Type'Read use Read;
- -- Three operations are used to optimize in the expansion of "for ... of"
- -- loops: the Next(Cursor) procedure in the visible part, and the following
- -- Pseudo_Reference and Get_Element_Access functions. See Sem_Ch5 for
- -- details.
+ -- See Ada.Containers.Vectors for documentation on the following
+
+ procedure _Next (Position : in out Cursor) renames Next;
+ procedure _Previous (Position : in out Cursor) renames Previous;
function Pseudo_Reference
(Container : aliased Set'Class) return Reference_Control_Type;
diff --git a/gcc/ada/scng.adb b/gcc/ada/scng.adb
--- a/gcc/ada/scng.adb
+++ b/gcc/ada/scng.adb
@@ -27,6 +27,7 @@ with Atree; use Atree;
with Csets; use Csets;
with Errout; use Errout;
with Hostparm; use Hostparm;
+with Lib; use Lib;
with Namet; use Namet;
with Opt; use Opt;
with Sinput; use Sinput;
@@ -2051,7 +2052,15 @@ package body Scng is
-- Underline character
when '_' =>
- Error_Msg_S ("identifier cannot start with underline");
+ -- Identifiers with leading underscores are not allowed in Ada.
+ -- However, we allow them in the run-time library, so we can
+ -- create names that are hidden from normal Ada code. For an
+ -- example, search for "Name_uNext", which is "_Next".
+
+ if not In_Internal_Unit (Scan_Ptr) then
+ Error_Msg_S ("identifier cannot start with underline");
+ end if;
+
Name_Len := 1;
Name_Buffer (1) := '_';
Scan_Ptr := Scan_Ptr + 1;
diff --git a/gcc/ada/snames.ads-tmpl b/gcc/ada/snames.ads-tmpl
--- a/gcc/ada/snames.ads-tmpl
+++ b/gcc/ada/snames.ads-tmpl
@@ -1375,7 +1375,9 @@ package Snames is
Name_Has_Element : constant Name_Id := N + $;
Name_Forward_Iterator : constant Name_Id := N + $;
Name_Reversible_Iterator : constant Name_Id := N + $;
+ Name_uNext : constant Name_Id := N + $;
Name_Previous : constant Name_Id := N + $;
+ Name_uPrevious : constant Name_Id := N + $;
Name_Pseudo_Reference : constant Name_Id := N + $;
Name_Reference_Control_Type : constant Name_Id := N + $;
Name_Get_Element_Access : constant Name_Id := N + $;