-- Cross references. -- Copyright (C) 2002, 2003, 2004, 2005 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 GNAT.Heap_Sort_A; with Flags; with Std_Package; with Errorout; use Errorout; with Nodes; package body Xrefs is type Xref_Type is record -- Where the cross-reference (or the name) appears. Loc : Location_Type; -- What the name refer to. Ref : Iir; -- Kind of reference (See package specification). Kind : Xref_Kind; end record; package Xref_Table is new Tables (Table_Index_Type => Natural, Table_Component_Type => Xref_Type, Table_Low_Bound => 0, Table_Initial => 128); function Get_Xref_Location (N : Xref) return Location_Type is begin return Xref_Table.Table (N).Loc; end Get_Xref_Location; function Get_Xref_Kind (N : Xref) return Xref_Kind is begin return Xref_Table.Table (N).Kind; end Get_Xref_Kind; function Get_Xref_Node (N : Xref) return Iir is begin return Xref_Table.Table (N).Ref; end Get_Xref_Node; function Get_Last_Xref return Xref is begin return Xref_Table.Last; end Get_Last_Xref; procedure Init is begin Xref_Table.Set_Last (Bad_Xref); end Init; procedure Add_Xref (Loc : Location_Type; Ref : Iir; Kind : Xref_Kind) is begin -- Check there is no xref for the same location to the same reference. -- (Note that a designatore may reference several declarations, this -- is possible in attribute specification for an overloadable name). -- This is a simple heuristic as this catch only two referenced in the -- row but efficient and should be enough to catch errors. pragma Assert (Xref_Table.Last < Xref_Table.First or else Xref_Table.Table (Xref_Table.Last).Loc /= Loc or else Xref_Table.Table (Xref_Table.Last).Ref /= Ref); Xref_Table.Append (Xref_Type'(Loc => Loc, Ref => Ref, Kind => Kind)); end Add_Xref; procedure Xref_Decl (Decl : Iir) is begin if Flags.Flag_Xref then Add_Xref (Get_Location (Decl), Decl, Xref_Decl); end if; end Xref_Decl; procedure Xref_Ref (Name : Iir; Decl : Iir) is begin if Flags.Flag_Xref then Add_Xref (Get_Location (Name), Decl, Xref_Ref); end if; end Xref_Ref; procedure Xref_Body (Bod : Iir; Spec : Iir) is begin if Flags.Flag_Xref then Add_Xref (Get_Location (Bod), Spec, Xref_Body); end if; end Xref_Body; procedure Xref_End (Loc : Location_Type; Decl : Iir) is begin if Flags.Flag_Xref then Add_Xref (Loc, Decl, Xref_End); end if; end Xref_End; procedure Xref_Keyword (Loc : Location_Type) is begin if Flags.Flag_Xref then Add_Xref (Loc, Null_Iir, Xref_Keyword); end if; end Xref_Keyword; procedure Xref_Name_1 (Name : Iir) is begin case Get_Kind (Name) is when Iir_Kind_Simple_Name | Iir_Kind_Selected_Name | Iir_Kind_Operator_Symbol | Iir_Kind_Character_Literal => declare