aboutsummaryrefslogtreecommitdiffstats
path: root/src/vhdl/vhdl-elocations.adb.in
diff options
context:
space:
mode:
Diffstat (limited to 'src/vhdl/vhdl-elocations.adb.in')
-rw-r--r--src/vhdl/vhdl-elocations.adb.in188
1 files changed, 188 insertions, 0 deletions
diff --git a/src/vhdl/vhdl-elocations.adb.in b/src/vhdl/vhdl-elocations.adb.in
new file mode 100644
index 000000000..1e2827b5f
--- /dev/null
+++ b/src/vhdl/vhdl-elocations.adb.in
@@ -0,0 +1,188 @@
+-- Extended locations for iir nodes
+-- Copyright (C) 2017 Tristan Gingold
+--
+-- GHDL is free software; you can redistribute it and/or modify it under
+-- the terms of the GNU General Public License as published by the Free
+-- Software Foundation; either version 2, or (at your option) any later
+-- version.
+--
+-- GHDL is distributed in the hope that it will be useful, but WITHOUT 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
+-- along with GHDL; see the file COPYING. If not, write to the Free
+-- Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+-- 02111-1307, USA.
+
+with Tables;
+with Nodes;
+with Vhdl.Elocations_Meta; use Vhdl.Elocations_Meta;
+
+package body Vhdl.Elocations is
+
+ -- Format of a node.
+ type Format_Type is
+ (
+ Format_None,
+ Format_L1,
+ Format_L2,
+ Format_L3,
+ Format_L4,
+ Format_L5,
+ Format_L6
+ );
+
+ -- Common fields are:
+
+ -- Fields of Format_None:
+
+ -- Fields of Format_L1:
+ -- Field1 : Location_Type
+
+ -- Fields of Format_L2:
+ -- Field1 : Location_Type
+ -- Field2 : Location_Type
+
+ -- Fields of Format_L3:
+ -- Field1 : Location_Type
+ -- Field2 : Location_Type
+ -- Field3 : Location_Type
+
+ -- Fields of Format_L4:
+ -- Field1 : Location_Type
+ -- Field2 : Location_Type
+ -- Field3 : Location_Type
+ -- Field4 : Location_Type
+
+ -- Fields of Format_L5:
+ -- Field1 : Location_Type
+ -- Field2 : Location_Type
+ -- Field3 : Location_Type
+ -- Field4 : Location_Type
+ -- Field5 : Location_Type
+
+ -- Fields of Format_L6:
+ -- Field1 : Location_Type
+ -- Field2 : Location_Type
+ -- Field3 : Location_Type
+ -- Field4 : Location_Type
+ -- Field5 : Location_Type
+ -- Field6 : Location_Type
+
+ function Get_Format (Kind : Iir_Kind) return Format_Type;
+
+ type Location_Index_Type is new Types.Nat32;
+ No_Location_Index : constant Location_Index_Type := 0;
+
+ package Elocations_Index_Table is new Tables
+ (Table_Component_Type => Location_Index_Type,
+ Table_Index_Type => Iir,
+ Table_Low_Bound => 2,
+ Table_Initial => 1024);
+
+ package Elocations_Table is new Tables
+ (Table_Component_Type => Location_Type,
+ Table_Index_Type => Location_Index_Type,
+ Table_Low_Bound => 2,
+ Table_Initial => 1024);
+
+ procedure Create_Elocations (N : Iir)
+ is
+ use Nodes;
+ Format : constant Format_Type := Get_Format (Get_Kind (N));
+ El : constant Iir := Elocations_Index_Table.Last;
+ Len : Location_Index_Type;
+ Idx : Location_Index_Type;
+ begin
+ pragma Assert (Format /= Format_None);
+
+ if El < N then
+ Elocations_Index_Table.Set_Last (N);
+ Elocations_Index_Table.Table (El + 1 .. N) :=
+ (others => No_Location_Index);
+ end if;
+
+ -- Must be called once.
+ pragma Assert (Elocations_Index_Table.Table (N) = No_Location_Index);
+
+ case Format is
+ when Format_None =>
+ raise Program_Error;
+ when Format_L1 =>
+ Len := 1;
+ when Format_L2 =>
+ Len := 2;
+ when Format_L3 =>
+ Len := 3;
+ when Format_L4 =>
+ Len := 4;
+ when Format_L5 =>
+ Len := 5;
+ when Format_L6 =>
+ Len := 6;
+ end case;
+
+ Idx := Elocations_Table.Last + 1;
+ Elocations_Index_Table.Table (N) := Idx;
+ Elocations_Table.Set_Last (Idx + Len - 1);
+ Elocations_Table.Table (Idx .. Idx + Len - 1) := (others => No_Location);
+ end Create_Elocations;
+
+ procedure Delete_Elocations (N : Iir) is
+ begin
+ -- Clear the corresponding index.
+ Elocations_Index_Table.Table (N) := No_Location_Index;
+
+ -- FIXME: keep free slots in chained list ?
+ end Delete_Elocations;
+
+ generic
+ Off : Location_Index_Type;
+ function Get_FieldX (N : Iir) return Location_Type;
+
+ generic
+ Off : Location_Index_Type;
+ procedure Set_FieldX (N : Iir; Loc : Location_Type);
+
+ function Get_FieldX (N : Iir) return Location_Type
+ is
+ use Nodes;
+ Idx : Location_Index_Type;
+ begin
+ pragma Assert (N <= Elocations_Index_Table.Last);
+ Idx := Elocations_Index_Table.Table (N);
+ return Elocations_Table.Table (Idx + Off - 1);
+ end Get_FieldX;
+
+ procedure Set_FieldX (N : Iir; Loc : Location_Type)
+ is
+ use Nodes;
+ Idx : Location_Index_Type;
+ begin
+ pragma Assert (N <= Elocations_Index_Table.Last);
+ Idx := Elocations_Index_Table.Table (N);
+ Elocations_Table.Table (Idx + Off - 1) := Loc;
+ end Set_FieldX;
+
+ function Get_Field1 is new Get_FieldX (1);
+ procedure Set_Field1 is new Set_FieldX (1);
+
+ function Get_Field2 is new Get_FieldX (2);
+ procedure Set_Field2 is new Set_FieldX (2);
+
+ function Get_Field3 is new Get_FieldX (3);
+ procedure Set_Field3 is new Set_FieldX (3);
+
+ function Get_Field4 is new Get_FieldX (4);
+ procedure Set_Field4 is new Set_FieldX (4);
+
+ function Get_Field5 is new Get_FieldX (5);
+ procedure Set_Field5 is new Set_FieldX (5);
+
+ function Get_Field6 is new Get_FieldX (6);
+ procedure Set_Field6 is new Set_FieldX (6);
+
+ -- Subprograms
+end Vhdl.Elocations;