aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sinfo-utils.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/sinfo-utils.adb')
-rw-r--r--gcc/ada/sinfo-utils.adb217
1 files changed, 217 insertions, 0 deletions
diff --git a/gcc/ada/sinfo-utils.adb b/gcc/ada/sinfo-utils.adb
new file mode 100644
index 0000000..abcda46
--- /dev/null
+++ b/gcc/ada/sinfo-utils.adb
@@ -0,0 +1,217 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S I N F O . U T I L S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2020-2021, 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- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
+-- for more details. You should have received a copy of the GNU General --
+-- Public License distributed with GNAT; see file COPYING3. If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Atree;
+with Seinfo;
+
+package body Sinfo.Utils is
+
+ -------------------------
+ -- Iterator Procedures --
+ -------------------------
+
+ procedure Next_Entity (N : in out Node_Id) is
+ begin
+ N := Next_Entity (N);
+ end Next_Entity;
+
+ procedure Next_Named_Actual (N : in out Node_Id) is
+ begin
+ N := Next_Named_Actual (N);
+ end Next_Named_Actual;
+
+ procedure Next_Rep_Item (N : in out Node_Id) is
+ begin
+ N := Next_Rep_Item (N);
+ end Next_Rep_Item;
+
+ procedure Next_Use_Clause (N : in out Node_Id) is
+ begin
+ N := Next_Use_Clause (N);
+ end Next_Use_Clause;
+
+ ------------------
+ -- End_Location --
+ ------------------
+
+ function End_Location (N : Node_Id) return Source_Ptr is
+ L : constant Uint := End_Span (N);
+ begin
+ if L = No_Uint then
+ return No_Location;
+ else
+ return Source_Ptr (Int (Sloc (N)) + UI_To_Int (L));
+ end if;
+ end End_Location;
+
+ --------------------
+ -- Get_Pragma_Arg --
+ --------------------
+
+ function Get_Pragma_Arg (Arg : Node_Id) return Node_Id is
+ begin
+ if Nkind (Arg) = N_Pragma_Argument_Association then
+ return Expression (Arg);
+ else
+ return Arg;
+ end if;
+ end Get_Pragma_Arg;
+
+ ----------------------
+ -- Set_End_Location --
+ ----------------------
+
+ procedure Set_End_Location (N : Node_Id; S : Source_Ptr) is
+ begin
+ Set_End_Span (N,
+ UI_From_Int (Int (S) - Int (Sloc (N))));
+ end Set_End_Location;
+
+ --------------------------
+ -- Pragma_Name_Unmapped --
+ --------------------------
+
+ function Pragma_Name_Unmapped (N : Node_Id) return Name_Id is
+ begin
+ return Chars (Pragma_Identifier (N));
+ end Pragma_Name_Unmapped;
+
+ ------------------------------------
+ -- Helpers for Walk_Sinfo_Fields* --
+ ------------------------------------
+
+ function Get_Node_Field_Union is new
+ Atree.Atree_Private_Part.Get_32_Bit_Field (Union_Id) with Inline;
+ procedure Set_Node_Field_Union is new
+ Atree.Atree_Private_Part.Set_32_Bit_Field (Union_Id) with Inline;
+
+ use Seinfo;
+
+ function Is_In_Union_Id (F_Kind : Field_Kind) return Boolean is
+ (F_Kind in Node_Id_Field
+ | List_Id_Field
+ | Elist_Id_Field
+ | Name_Id_Field
+ | String_Id_Field
+ | Uint_Field
+ | Ureal_Field
+ | Union_Id_Field);
+ -- True if the field type is one that can be converted to Types.Union_Id
+
+ -----------------------
+ -- Walk_Sinfo_Fields --
+ -----------------------
+
+ procedure Walk_Sinfo_Fields (N : Node_Id) is
+ Fields : Node_Field_Array renames
+ Node_Field_Table (Nkind (N)).all;
+
+ begin
+ for J in Fields'Range loop
+ if Fields (J) /= Link then -- Don't walk Parent!
+ declare
+ Desc : Field_Descriptor renames
+ Node_Field_Descriptors (Fields (J));
+ begin
+ if Is_In_Union_Id (Desc.Kind) then
+ Action (Get_Node_Field_Union (N, Desc.Offset));
+ end if;
+ end;
+ end if;
+ end loop;
+ end Walk_Sinfo_Fields;
+
+ --------------------------------
+ -- Walk_Sinfo_Fields_Pairwise --
+ --------------------------------
+
+ procedure Walk_Sinfo_Fields_Pairwise (N1, N2 : Node_Id) is
+ pragma Assert (Nkind (N1) = Nkind (N2));
+
+ Fields : Node_Field_Array renames
+ Node_Field_Table (Nkind (N1)).all;
+
+ begin
+ for J in Fields'Range loop
+ if Fields (J) /= Link then -- Don't walk Parent!
+ declare
+ Desc : Field_Descriptor renames
+ Node_Field_Descriptors (Fields (J));
+ begin
+ if Is_In_Union_Id (Desc.Kind) then
+ Set_Node_Field_Union
+ (N1, Desc.Offset,
+ Transform (Get_Node_Field_Union (N2, Desc.Offset)));
+ end if;
+ end;
+ end if;
+ end loop;
+ end Walk_Sinfo_Fields_Pairwise;
+
+ ---------------------
+ -- Map_Pragma_Name --
+ ---------------------
+
+ -- We don't want to introduce a dependence on some hash table package or
+ -- similar, so we use a simple array of Key => Value pairs, and do a linear
+ -- search. Linear search is plenty efficient, given that we don't expect
+ -- more than a couple of entries in the mapping.
+
+ type Name_Pair is record
+ Key : Name_Id;
+ Value : Name_Id;
+ end record;
+
+ type Pragma_Map_Index is range 1 .. 100;
+ Pragma_Map : array (Pragma_Map_Index) of Name_Pair;
+ Last_Pair : Pragma_Map_Index'Base range 0 .. Pragma_Map_Index'Last := 0;
+
+ procedure Map_Pragma_Name (From, To : Name_Id) is
+ begin
+ if Last_Pair = Pragma_Map'Last then
+ raise Too_Many_Pragma_Mappings;
+ end if;
+
+ Last_Pair := Last_Pair + 1;
+ Pragma_Map (Last_Pair) := (Key => From, Value => To);
+ end Map_Pragma_Name;
+
+ -----------------
+ -- Pragma_Name --
+ -----------------
+
+ function Pragma_Name (N : Node_Id) return Name_Id is
+ Result : constant Name_Id := Pragma_Name_Unmapped (N);
+ begin
+ for J in Pragma_Map'First .. Last_Pair loop
+ if Result = Pragma_Map (J).Key then
+ return Pragma_Map (J).Value;
+ end if;
+ end loop;
+
+ return Result;
+ end Pragma_Name;
+
+end Sinfo.Utils;