diff options
Diffstat (limited to 'src/vhdl/vhdl-sem_scopes.adb')
-rw-r--r-- | src/vhdl/vhdl-sem_scopes.adb | 1672 |
1 files changed, 1672 insertions, 0 deletions
diff --git a/src/vhdl/vhdl-sem_scopes.adb b/src/vhdl/vhdl-sem_scopes.adb new file mode 100644 index 000000000..8e616bd4b --- /dev/null +++ b/src/vhdl/vhdl-sem_scopes.adb @@ -0,0 +1,1672 @@ +-- Semantic analysis. +-- 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 Logging; use Logging; +with Tables; +with Flags; use Flags; +with Name_Table; -- use Name_Table; +with Files_Map; use Files_Map; +with Errorout; use Errorout; +with Iirs_Utils; use Iirs_Utils; + +package body Vhdl.Sem_Scopes is + -- An interpretation cell is the element of the simply linked list + -- of interpretation for an identifier. + -- Interpretation cells are stored in table Interpretations. + type Interpretation_Cell is record + -- The declaration for this interpretation. + Decl: Iir; + + -- If True, the declaration is potentially visible (ie visible via a + -- use clause). + Is_Potential : Boolean; + + -- If True, previous declarations in PREV chain are hidden and shouldn't + -- be considered. + Prev_Hidden : Boolean; + + -- Previous interpretation for this identifier. + -- If No_Name_Interpretation, this (not PREV) interpretation is the last + -- one. If Prev_Hidden is True, PREV must be ignored. If Prev_Hidden is + -- false, the identifier is overloaded. + Prev: Name_Interpretation_Type; + + -- Previous added identifier in the declarative region. This forms a + -- linked list used to remove interpretations when a declarative + -- region is closed. + Prev_In_Region : Name_Id; + end record; + pragma Pack (Interpretation_Cell); + + package Interpretations is new Tables + (Table_Component_Type => Interpretation_Cell, + Table_Index_Type => Name_Interpretation_Type, + Table_Low_Bound => First_Valid_Interpretation, + Table_Initial => 1024); + + -- Cached value of Prev_In_Region of current region. + Last_In_Region : Name_Id := Null_Identifier; + + -- First interpretation in the current declarative region. + Current_Region_Start : Name_Interpretation_Type := + First_Valid_Interpretation; + + -- First valid interpretation. All interpretations smaller than this + -- value are part of a previous (and nested) analysis and must not be + -- considered. + First_Interpretation : Name_Interpretation_Type := + First_Valid_Interpretation; + + -- List of non-local hidden declarations. + type Hide_Index is new Nat32; + No_Hide_Index : constant Hide_Index := 0; + + package Hidden_Decls is new Tables + (Table_Component_Type => Name_Interpretation_Type, + Table_Index_Type => Hide_Index, + Table_Low_Bound => No_Hide_Index + 1, + Table_Initial => 32); + + -- First non-local hidden declarations. In VHDL, it is possible to hide + -- an overloaded declaration (by declaring a subprogram with the same + -- profile). If the overloaded declaration is local, the interpretation + -- can simply be modified. But if it is not local, the interpretation is + -- removed from the chain and saved in the Hidden_Decls table. + First_Hide_Index : Hide_Index := No_Hide_Index; + + -- To manage the list of interpretation and to add informations to this + -- list, a stack is used. + -- Elements of stack can be of kind: + -- Save_Cell: + -- the element contains the interpretation INTER for the indentifier ID + -- for the outer declarative region. + -- A save cell is always created each time a declaration is added to save + -- the previous interpretation. + -- Region_Start: + -- A new declarative region start at interpretation INTER. Here, INTER + -- is used as an index in the interpretations stack (table). + -- ID is used as an index into the unidim_array stack. + -- Barrier_start, Barrier_end: + -- All currents interpretations are saved between both INTER, and + -- are cleared. This is used to call semantic during another semantic. + + type Scope_Cell_Kind_Type is (Scope_Start, Scope_Region); + + type Scope_Cell is record + Kind: Scope_Cell_Kind_Type; + + -- Values for the previous scope. + Saved_Last_In_Region : Name_Id; + Saved_Region_Start : Name_Interpretation_Type; + Saved_First_Hide_Index : Hide_Index; + Saved_First_Interpretation : Name_Interpretation_Type; + end record; + + package Scopes is new Tables + (Table_Component_Type => Scope_Cell, + Table_Index_Type => Natural, + Table_Low_Bound => 1, + Table_Initial => 64); + + function Valid_Interpretation (Inter : Name_Interpretation_Type) + return Boolean is + begin + return Inter >= First_Interpretation; + end Valid_Interpretation; + + -- Return True iff NI means there is a conflict for the identifier: no + -- valid interpretation due to potentially visible homoraph. + function Is_Conflict_Declaration (Ni : Name_Interpretation_Type) + return Boolean is + begin + pragma Assert (Valid_Interpretation (Ni)); + return Interpretations.Table (Ni).Decl = Null_Iir; + end Is_Conflict_Declaration; + + -- Get the current interpretation for ID. The result is raw: it may not + -- be valid. + function Get_Interpretation_Raw (Id : Name_Id) + return Name_Interpretation_Type is + begin + return Name_Interpretation_Type (Name_Table.Get_Name_Info (Id)); + end Get_Interpretation_Raw; + + procedure Set_Interpretation + (Id : Name_Id; Inter : Name_Interpretation_Type) is + begin + Name_Table.Set_Name_Info (Id, Int32 (Inter)); + end Set_Interpretation; + + function Get_Interpretation_From_Raw (Inter : Name_Interpretation_Type) + return Name_Interpretation_Type is + begin + if Valid_Interpretation (Inter) + and then not Is_Conflict_Declaration (Inter) + then + -- In the current scopes set and not a conflict. + return Inter; + else + return No_Name_Interpretation; + end if; + end Get_Interpretation_From_Raw; + + function Get_Interpretation (Id : Name_Id) + return Name_Interpretation_Type is + begin + return Get_Interpretation_From_Raw (Get_Interpretation_Raw (Id)); + end Get_Interpretation; + + procedure Check_Interpretations; + pragma Unreferenced (Check_Interpretations); + + procedure Check_Interpretations + is + Inter: Name_Interpretation_Type; + Last : constant Name_Interpretation_Type := Interpretations.Last; + Err : Boolean; + begin + Err := False; + for I in 0 .. Name_Table.Last_Name_Id loop + Inter := Get_Interpretation (I); + if Inter > Last then + Log_Line ("bad interpretation for " & Name_Table.Image (I)); + Err := True; + end if; + end loop; + if Err then + raise Internal_Error; + end if; + end Check_Interpretations; + + procedure Push_Interpretations is + begin + Scopes.Append ((Kind => Scope_Start, + Saved_Last_In_Region => Last_In_Region, + Saved_Region_Start => Current_Region_Start, + Saved_First_Hide_Index => First_Hide_Index, + Saved_First_Interpretation => First_Interpretation)); + Last_In_Region := Null_Identifier; + Current_Region_Start := Interpretations.Last + 1; + First_Hide_Index := Hidden_Decls.Last + 1; + First_Interpretation := Interpretations.Last + 1; + end Push_Interpretations; + + procedure Pop_Interpretations + is + Cell : Scope_Cell renames Scopes.Table (Scopes.Last); + begin + pragma Assert (Scopes.Table (Scopes.Last).Kind = Scope_Start); + + -- All the declarative regions must have been removed. + pragma Assert (Last_In_Region = Null_Identifier); + pragma Assert (Current_Region_Start = Interpretations.Last + 1); + pragma Assert (First_Hide_Index = Hidden_Decls.Last + 1); + pragma Assert (First_Interpretation = Interpretations.Last + 1); + + Last_In_Region := Cell.Saved_Last_In_Region; + Current_Region_Start := Cell.Saved_Region_Start; + First_Hide_Index := Cell.Saved_First_Hide_Index; + First_Interpretation := Cell.Saved_First_Interpretation; + + Scopes.Decrement_Last; + end Pop_Interpretations; + + -- Create a new declarative region. + -- Simply push a region_start cell and update current_scope_start. + procedure Open_Declarative_Region is + begin + Scopes.Append ((Kind => Scope_Region, + Saved_Last_In_Region => Last_In_Region, + Saved_Region_Start => Current_Region_Start, + Saved_First_Hide_Index => First_Hide_Index, + Saved_First_Interpretation => No_Name_Interpretation)); + Last_In_Region := Null_Identifier; + Current_Region_Start := Interpretations.Last + 1; + First_Hide_Index := Hidden_Decls.Last + 1; + end Open_Declarative_Region; + + -- Close a declarative region. + -- Update interpretation of identifiers. + procedure Close_Declarative_Region + is + Cell : Scope_Cell renames Scopes.Table (Scopes.Last); + Id : Name_Id; + begin + pragma Assert (Cell.Kind = Scope_Region); + + -- Restore hidden declarations. + for I in reverse First_Hide_Index .. Hidden_Decls.Last loop + declare + Inter : constant Name_Interpretation_Type := + Hidden_Decls.Table (I); + Prev_Inter, Next_Inter : Name_Interpretation_Type; + begin + Prev_Inter := Interpretations.Table (Inter).Prev; + Next_Inter := Interpretations.Table (Prev_Inter).Prev; + Interpretations.Table (Inter).Prev := Next_Inter; + Interpretations.Table (Prev_Inter).Prev := Inter; + end; + end loop; + Hidden_Decls.Set_Last (First_Hide_Index - 1); + + -- Remove interpretations of that region. + Id := Last_In_Region; + if Id /= Null_Identifier then + declare + Inter : Name_Interpretation_Type; + begin + loop + Inter := Get_Interpretation_Raw (Id); + pragma Assert (Inter >= Current_Region_Start); + Set_Interpretation (Id, Interpretations.Table (Inter).Prev); + Id := Interpretations.Table (Inter).Prev_In_Region; + exit when Id = Null_Identifier; + end loop; + pragma Assert (Inter = Current_Region_Start); + end; + Interpretations.Set_Last (Current_Region_Start - 1); + end if; + + Last_In_Region := Cell.Saved_Last_In_Region; + Current_Region_Start := Cell.Saved_Region_Start; + First_Hide_Index := Cell.Saved_First_Hide_Index; + + Scopes.Decrement_Last; + end Close_Declarative_Region; + + procedure Open_Scope_Extension renames Open_Declarative_Region; + procedure Close_Scope_Extension renames Close_Declarative_Region; + + function Get_Next_Interpretation (Ni : Name_Interpretation_Type) + return Name_Interpretation_Type + is + pragma Assert (Valid_Interpretation (Ni)); + Cell : Interpretation_Cell renames Interpretations.Table (Ni); + begin + if Cell.Prev_Hidden + or else not Valid_Interpretation (Cell.Prev) + then + return No_Name_Interpretation; + else + return Cell.Prev; + end if; + end Get_Next_Interpretation; + + function Get_Declaration (Ni : Name_Interpretation_Type) return Iir is + begin + pragma Assert (Valid_Interpretation (Ni)); + return Interpretations.Table (Ni).Decl; + end Get_Declaration; + + function Get_Under_Interpretation (Id : Name_Id) + return Name_Interpretation_Type + is + Inter : constant Name_Interpretation_Type := Get_Interpretation (Id); + begin + -- ID has no interpretation. + -- So, there is no 'under' interpretation (FIXME: prove it). + pragma Assert (Valid_Interpretation (Inter)); + + declare + Cell : Interpretation_Cell renames Interpretations.Table (Inter); + Prev : constant Name_Interpretation_Type := Cell.Prev; + begin + -- Get_Under_Interpretation can be used only to get a hidden + -- interpretation. + pragma Assert (Cell.Prev_Hidden); + + if Valid_Interpretation (Prev) + -- Not a conflict one (use clauses). + and then Get_Declaration (Prev) /= Null_Iir + then + return Prev; + else + return No_Name_Interpretation; + end if; + end; + end Get_Under_Interpretation; + + function Strip_Non_Object_Alias (Decl : Iir) return Iir + is + Res : Iir; + begin + Res := Decl; + if Get_Kind (Res) = Iir_Kind_Non_Object_Alias_Declaration then + Res := Get_Named_Entity (Get_Name (Res)); + end if; + return Res; + end Strip_Non_Object_Alias; + + function Get_Non_Alias_Declaration (Ni : Name_Interpretation_Type) + return Iir is + begin + return Strip_Non_Object_Alias (Get_Declaration (Ni)); + end Get_Non_Alias_Declaration; + + -- Return TRUE if INTER was made directly visible via a use clause. + function Is_Potentially_Visible (Inter : Name_Interpretation_Type) + return Boolean is + begin + return Interpretations.Table (Inter).Is_Potential; + end Is_Potentially_Visible; + + -- Return TRUE iif DECL can be overloaded. + function Is_Overloadable (Decl : Iir) return Boolean is + begin + -- LRM93 10.3: + -- The overloaded declarations considered in this chapter are those for + -- subprograms and enumeration literals. + case Get_Kind (Decl) is + when Iir_Kind_Enumeration_Literal + | Iir_Kind_Function_Declaration + | Iir_Kind_Procedure_Declaration + | Iir_Kind_Interface_Function_Declaration + | Iir_Kind_Interface_Procedure_Declaration => + return True; + when Iir_Kind_Non_Object_Alias_Declaration => + case Get_Kind (Get_Named_Entity (Get_Name (Decl))) is + when Iir_Kind_Enumeration_Literal + | Iir_Kind_Function_Declaration + | Iir_Kind_Procedure_Declaration + | Iir_Kind_Interface_Function_Declaration + | Iir_Kind_Interface_Procedure_Declaration => + return True; + when Iir_Kind_Non_Object_Alias_Declaration => + raise Internal_Error; + when others => + return False; + end case; + when others => + return False; + end case; + end Is_Overloadable; + + -- Return TRUE if INTER was made direclty visible in the current + -- declarative region. + function Is_In_Current_Declarative_Region (Inter : Name_Interpretation_Type) + return Boolean is + begin + return Inter >= Current_Region_Start; + end Is_In_Current_Declarative_Region; + + -- Emit a warning when DECL hides PREV_DECL. + procedure Warning_Hide (Decl : Iir; Prev_Decl : Iir) + is + begin + if Get_Kind (Decl) in Iir_Kinds_Interface_Declaration + and then Get_Kind (Get_Parent (Decl)) = Iir_Kind_Component_Declaration + then + -- Do not warn when an interface in a component hides a declaration. + -- This is a common case (eg: in testbenches), and there is no real + -- hiding. + return; + end if; + + if Get_Kind (Decl) = Iir_Kind_Element_Declaration then + -- Do not warn for record elements. They are used by selection. + return; + end if; + + if Decl = Prev_Decl then + -- Can happen in configuration. No real hidding. + return; + end if; + + Warning_Msg_Sem (Warnid_Hide, +Decl, + "declaration of %i hides %n", (+Decl, +Prev_Decl)); + end Warning_Hide; + + -- Add interpretation DECL to the identifier of DECL. + -- POTENTIALLY is true if the identifier comes from a use clause. + procedure Add_Name (Decl : Iir; Ident : Name_Id; Potentially : Boolean) + is + -- Current interpretation of ID. This is the one before DECL is + -- added (if so). + Raw_Inter : constant Name_Interpretation_Type := + Get_Interpretation_Raw (Ident); + Current_Inter : constant Name_Interpretation_Type := + Get_Interpretation_From_Raw (Raw_Inter); + Current_Decl : Iir; + + -- Add DECL in the chain of interpretation for the identifier. + procedure Add_New_Interpretation (Hid_Prev : Boolean; D : Iir := Decl) is + begin + Interpretations.Append ((Decl => D, + Prev => Raw_Inter, + Is_Potential => Potentially, + Prev_Hidden => Hid_Prev, + Prev_In_Region => Last_In_Region)); + Set_Interpretation (Ident, Interpretations.Last); + Last_In_Region := Ident; + end Add_New_Interpretation; + begin + if Ident = Null_Identifier then + -- Missing identifier can happen only in case of parse error. + pragma Assert (Flags.Flag_Force_Analysis); + return; + end if; + + if not Valid_Interpretation (Raw_Inter) then + -- Very simple: no hidding, no overloading. + Add_New_Interpretation (True); + return; + end if; + + if Is_Conflict_Declaration (Raw_Inter) then + if Potentially then + -- Yet another conflicting interpretation. + return; + else + -- Very simple: no hidding, no overloading. + -- (current interpretation is Conflict_Interpretation if there is + -- only potentially visible declarations that are not made + -- directly visible). + -- Note: in case of conflict interpretation, it may be unnecessary + -- to keep the current interpretation (but it is simpler as is). + Add_New_Interpretation (True); + return; + end if; + end if; + + if Potentially then + -- Do not re-add a potential decl. This handles cases like: + -- 'use p.all; use p.all;'. + -- FIXME: add a flag (or reuse Visible_Flag) to avoid walking all + -- the interpretations. + declare + Inter : Name_Interpretation_Type := Current_Inter; + begin + while Valid_Interpretation (Inter) loop + if Get_Declaration (Inter) = Decl then + return; + end if; + Inter := Get_Next_Interpretation (Inter); + end loop; + end; + end if; + + -- LRM 10.3 Visibility + -- Each of two declarations is said to be a homograph of the other if + -- both declarations have the same identifier, operator symbol, or + -- character literal, and overloading is allowed for at most one + -- of the two. + -- + -- GHDL: the condition 'overloading is allowed for at most one of the + -- two' is false iff overloading is allowed for both; this is a nand. + + -- Note: at this stage, current_inter is valid. + Current_Decl := Get_Declaration (Current_Inter); + + if Is_Overloadable (Current_Decl) and then Is_Overloadable (Decl) then + -- Current_Inter and Decl overloads (well, they have the same + -- designator). + + -- LRM 10.3 Visibility + -- If overloading is allowed for both declarations, then each of the + -- two is a homograph of the other if they have the same identifier, + -- operator symbol or character literal, as well as the same + -- parameter and result profile. + + declare + Homograph : Name_Interpretation_Type; + Prev_Homograph : Name_Interpretation_Type; + + -- Hide HOMOGRAPH (ie unlink it from the chain of interpretation). + procedure Hide_Homograph + is + S : Name_Interpretation_Type; + begin + if Prev_Homograph = No_Name_Interpretation then + Prev_Homograph := Interpretations.Last; + end if; + + -- PREV_HOMOGRAPH must be the interpretation just before + -- HOMOGRAPH. + pragma Assert + (Interpretations.Table (Prev_Homograph).Prev = Homograph); + + -- Hide previous interpretation. + Hidden_Decls.Append (Homograph); + + S := Interpretations.Table (Homograph).Prev; + Interpretations.Table (Homograph).Prev := Prev_Homograph; + Interpretations.Table (Prev_Homograph).Prev := S; + end Hide_Homograph; + + function Get_Hash_Non_Alias (D : Iir) return Iir_Int32 is + begin + return Get_Subprogram_Hash (Strip_Non_Object_Alias (D)); + end Get_Hash_Non_Alias; + + -- Return True iff D is an implicit declaration (either a + -- subprogram or an implicit alias). + function Is_Implicit_Declaration (D : Iir) return Boolean is + begin + case Get_Kind (D) is + when Iir_Kind_Non_Object_Alias_Declaration => + return Get_Implicit_Alias_Flag (D); + when Iir_Kind_Enumeration_Literal => + return False; + when Iir_Kind_Procedure_Declaration + | Iir_Kind_Function_Declaration => + return Is_Implicit_Subprogram (D); + when others => + Error_Kind ("is_implicit_declaration", D); + end case; + end Is_Implicit_Declaration; + + -- Return TRUE iff D is an implicit alias of an implicit + -- subprogram. + function Is_Implicit_Alias (D : Iir) return Boolean is + begin + -- FIXME: Is it possible to have an implicit alias of an + -- explicit subprogram ? Yes for enumeration literal and + -- physical units. + return Get_Kind (D) = Iir_Kind_Non_Object_Alias_Declaration + and then Get_Implicit_Alias_Flag (D) + and then Is_Implicit_Subprogram (Get_Named_Entity + (Get_Name (D))); + end Is_Implicit_Alias; + + -- Replace the homograph of DECL by DECL. + procedure Replace_Homograph is + begin + Interpretations.Table (Homograph).Decl := Decl; + end Replace_Homograph; + + Decl_Hash : Iir_Int32; + Hash : Iir_Int32; + begin + Decl_Hash := Get_Hash_Non_Alias (Decl); + -- The hash must have been computed. + pragma Assert (Decl_Hash /= 0); + + -- LRM02 10.3 Visibility + -- Each of two declarations is said to be a /homograph/ of the + -- other if both declarations have the same identifier, operator + -- symbol, or character literal, and if overloading is allowed for + -- at most one of the two. + -- + -- LRM08 12.3 Visibility + -- Each of two declarations is said to be a /homograph/ of the + -- other if and only if both declarations have the same + -- designator, and they denote different named entities, and + -- either overloading is allows for at most one of the two, or + -- overloading is allowed for both declarations and they have the + -- same parameter and result type profile. + + -- GHDL: here we are in the case when both declarations are + -- overloadable. Also, always follow the LRM08 rules as they fix + -- issues. + -- GHDL: Special case for a second declaration with the same + -- designator and that denotes the same named entity than a + -- previous one (that would be an alias): according to the LRM, + -- they are both visible and there are no ambiguity as they + -- denotes the same named entity. In GHDL, the new one hides the + -- previous one. The behaviour should be the same. + + -- Find an homograph of this declaration (and also keep the + -- interpretation just before it in the chain). + Homograph := Current_Inter; + Prev_Homograph := No_Name_Interpretation; + while Homograph /= No_Name_Interpretation loop + Current_Decl := Get_Declaration (Homograph); + Hash := Get_Hash_Non_Alias (Current_Decl); + exit when Decl_Hash = Hash + and then Is_Same_Profile (Decl, Current_Decl); + Prev_Homograph := Homograph; + Homograph := Get_Next_Interpretation (Homograph); + end loop; + + if Homograph = No_Name_Interpretation then + -- Simple case: no homograph. + Add_New_Interpretation (False); + return; + end if; + + -- There is an homograph (or the named entity is the same). + if Potentially then + -- Added DECL would be made potentially visible. + + -- LRM93 10.4 1) / LRM08 12.4 a) Use Clauses + -- 1. A potentially visible declaration is not made + -- directly visible if the place considered is within the + -- immediate scope of a homograph of the declaration. + if not Is_Potentially_Visible (Homograph) then + return; + end if; + + -- LRM08 12.4 Use Clauses + -- b) If two potentially visible declarations are homograph + -- and one is explicitly declared and the other is + -- implicitly declared, then the implicit declaration is + -- not made directly visible. + if (Flags.Flag_Explicit or else Flags.Vhdl_Std >= Vhdl_08) + and then Is_Potentially_Visible (Homograph) + then + declare + Implicit_Current_Decl : constant Boolean := + Is_Implicit_Declaration (Current_Decl); + Implicit_Decl : constant Boolean := + Is_Implicit_Declaration (Decl); + begin + if Implicit_Current_Decl and then not Implicit_Decl then + if Is_In_Current_Declarative_Region (Homograph) then + Replace_Homograph; + else + -- Insert DECL and hide homograph. + Add_New_Interpretation (False); + Hide_Homograph; + end if; + return; + elsif not Implicit_Current_Decl and then Implicit_Decl + then + -- Discard decl. + return; + elsif Strip_Non_Object_Alias (Decl) + = Strip_Non_Object_Alias (Current_Decl) + then + -- This rule is not written clearly in the LRM, but + -- if two designators denote the same named entity, + -- no need to make both visible. + return; + end if; + end; + end if; + + -- GHDL: if the homograph is in the same declarative + -- region than DECL, it must be an implicit declaration + -- to be hidden. + -- FIXME: this rule is not in the LRM93, but it is necessary + -- so that explicit declaration hides the implicit one. + if Flags.Vhdl_Std < Vhdl_08 + and then not Flags.Flag_Explicit + and then Get_Parent (Decl) = Get_Parent (Current_Decl) + then + declare + Implicit_Current_Decl : constant Boolean := + Is_Implicit_Subprogram (Current_Decl); + Implicit_Decl : constant Boolean := + Is_Implicit_Subprogram (Decl); + begin + if Implicit_Current_Decl and not Implicit_Decl then + -- Note: no need to save previous interpretation, as + -- it is in the same declarative region. + -- Replace the previous homograph with DECL. + Replace_Homograph; + return; + elsif not Implicit_Current_Decl and Implicit_Decl then + -- As we have replaced the homograph, it is possible + -- than the implicit declaration is re-added (by + -- a new use clause). Discard it. + return; + end if; + end; + end if; + + -- The homograph was made visible in an outer declarative + -- region. Therefore, it must not be hidden. + Add_New_Interpretation (False); + + return; + else + -- Added DECL would be made directly visible. + + if not Is_Potentially_Visible (Homograph) then + -- The homograph was also declared in that declarative + -- region or in an inner one. + if Is_In_Current_Declarative_Region (Homograph) then + -- ... and was declared in the same region + + -- To sum up: at this point both DECL and CURRENT_DECL + -- are overloadable, have the same profile (but may be + -- aliases) and are declared in the same declarative + -- region. + + -- LRM08 12.3 Visibility + -- LRM93 10.3 Visibility + -- Two declarations that occur immediately within + -- the same declarative regions [...] shall not be + -- homograph, unless exactely one of them is the + -- implicit declaration of a predefined operation, + + -- LRM08 12.3 Visibility + -- or is an implicit alias of such implicit declaration. + -- + -- GHDL: FIXME: 'implicit alias' + + -- LRM08 12.3 Visibility + -- LRM93 10.3 Visibility + -- Each of two declarations is said to be a + -- homograph of the other if and only if both + -- declarations have the same designator, [...] + -- + -- LRM08 12.3 Visibility + -- [...] and they denote different named entities, + -- and [...] + declare + Is_Decl_Implicit : Boolean; + Is_Current_Decl_Implicit : Boolean; + begin + if Flags.Vhdl_Std >= Vhdl_08 then + Is_Current_Decl_Implicit := + Is_Implicit_Subprogram (Current_Decl) + or else Is_Implicit_Alias (Current_Decl); + Is_Decl_Implicit := Is_Implicit_Subprogram (Decl) + or else Is_Implicit_Alias (Decl); + + -- If they denote the same entity, they aren't + -- homograph. + if Strip_Non_Object_Alias (Decl) + = Strip_Non_Object_Alias (Current_Decl) + then + if Is_Current_Decl_Implicit + and then not Is_Decl_Implicit + then + -- They aren't homograph but DECL is stronger + -- (at it is not an implicit declaration) + -- than CURRENT_DECL + Replace_Homograph; + end if; + + return; + end if; + + if Is_Decl_Implicit + and then not Is_Current_Decl_Implicit + then + -- Re-declaration of an implicit subprogram via + -- an implicit alias is simply discarded. + return; + end if; + else + -- Can an implicit subprogram declaration appears + -- after an explicit one in vhdl 93? I don't + -- think so. + Is_Decl_Implicit := Is_Implicit_Subprogram (Decl); + Is_Current_Decl_Implicit := + Is_Implicit_Subprogram (Current_Decl); + end if; + + if not (Is_Decl_Implicit xor Is_Current_Decl_Implicit) + then + Error_Msg_Sem + (+Decl, "redeclaration of %n defined at %l", + (+Current_Decl, +Current_Decl)); + return; + end if; + + if not Is_Decl_Implicit and Is_Current_Decl_Implicit + then + -- DECL 'overrides' the predefined current + -- declaration. + + -- LRM93 10.3 Visibility + -- In such cases, a predefined operation is always + -- hidden by the other homograph. Where hidden in + -- this manner, an implicit declaration is hidden + -- within the entire scope of the other declaration + -- (regardless of which declaration occurs first); + -- the implicit declaration is visible neither by + -- selection nor directly. + Set_Visible_Flag (Current_Decl, False); + if Get_Kind (Decl) + in Iir_Kinds_Subprogram_Declaration + then + Set_Hide_Implicit_Flag (Decl, True); + end if; + end if; + end; + else + -- GHDL: hide directly visible declaration declared in + -- an outer region. + null; + end if; + else + -- LRM 10.4 Use Clauses + -- 1. A potentially visible declaration is not made + -- directly visible if the place considered is within the + -- immediate scope of a homograph of the declaration. + + -- GHDL: hide the potentially visible declaration. + null; + end if; + Add_New_Interpretation (False); + + Hide_Homograph; + return; + end if; + end; + end if; + + -- The current interpretation and the new one aren't overloadable, ie + -- they are homograph (well almost). + + if Is_Potentially_Visible (Current_Inter) then + if Potentially then + -- LRM93 10.4 2) / LRM08 12.4 c) Use clauses + -- Potentially visible declarations that have the same + -- designator are not made directly visible unless each of + -- them is either an enumeration literal specification or + -- the declaration of a subprogram. + if Decl = Get_Declaration (Current_Inter) then + -- The rule applies only for distinct declaration. + -- This handles 'use p.all; use P.all;'. + -- FIXME: this should have been handled at the start of + -- this subprogram. + raise Internal_Error; + return; + end if; + + -- LRM08 12.3 Visibility + -- Each of two declarations is said to be a homograph of the + -- other if and only if both declarations have the same + -- designator; and they denote different named entities, [...] + if Flags.Vhdl_Std >= Vhdl_08 then + if Strip_Non_Object_Alias (Decl) + = Strip_Non_Object_Alias (Current_Decl) + then + return; + end if; + end if; + + -- Conflict. + Add_New_Interpretation (True, Null_Iir); + return; + else + -- LRM93 10.4 item #1 + -- A potentially visible declaration is not made directly + -- visible if the place considered is within the immediate + -- scope of a homograph of the declaration. + -- GHDL: Could directly replace the previous interpretation + -- (added in same scope), but don't do that for entity + -- declarations, since it is used to find default binding. + Add_New_Interpretation (True); + return; + end if; + else + -- There is already a declaration in the current scope. + if Potentially then + -- LRM93 §10.4 item #1 + -- Discard the new and potentially visible declaration. + -- However, add the type. + -- FIXME: Add_In_Visible_List (Ident, Decl); + return; + else + if Is_In_Current_Declarative_Region (Current_Inter) then + -- They are perhaps visible in the same declarative region. + + -- LRM93 11.2 + -- If two or more logical names having the same + -- identifier appear in library clauses in the same + -- context, the second and subsequent occurences of the + -- logical name have no effect. The same is true of + -- logical names appearing both in the context clause + -- of a primary unit and in the context clause of a + -- corresponding secondary unit. + -- GHDL: we apply this rule with VHDL-87, because of implicits + -- library clauses STD and WORK. + if Get_Kind (Decl) = Iir_Kind_Library_Declaration + and then + Get_Kind (Current_Decl) = Iir_Kind_Library_Declaration + then + return; + end if; + + -- None of the two declarations are potentially visible, ie + -- both are visible. + -- LRM §10.3: + -- Two declarations that occur immediately within the same + -- declarative region must not be homographs, + -- FIXME: unless one of them is the implicit declaration of a + -- predefined operation. + Error_Msg_Sem + (+Decl, "identifier %i already used for a declaration", + (1 => +Ident), Cont => True); + Error_Msg_Sem + (+Current_Decl, "previous declaration: %n", +Current_Decl); + return; + else + -- Homograph, not in the same scope. + -- LRM §10.3: + -- A declaration is said to be hidden within (part of) an inner + -- declarative region if the inner region contains an homograph + -- of this declaration; the outer declaration is the hidden + -- within the immediate scope of the inner homograph. + if Is_Warning_Enabled (Warnid_Hide) + and then not Is_Potentially_Visible (Current_Inter) + then + Warning_Hide (Decl, Current_Decl); + end if; + + Add_New_Interpretation (True); + return; + end if; + end if; + end if; + end Add_Name; + + procedure Add_Name (Decl: Iir) is + begin + Add_Name (Decl, Get_Identifier (Decl), False); + end Add_Name; + + procedure Replace_Name (Id: Name_Id; Old : Iir; Decl: Iir) + is + Inter : Name_Interpretation_Type; + begin + Inter := Get_Interpretation (Id); + loop + exit when Get_Declaration (Inter) = Old; + Inter := Get_Next_Interpretation (Inter); + pragma Assert (Valid_Interpretation (Inter)); + end loop; + Interpretations.Table (Inter).Decl := Decl; + pragma Assert (Get_Next_Interpretation (Inter) = No_Name_Interpretation); + end Replace_Name; + + procedure Name_Visible (Decl : Iir) is + begin + -- A name can be made visible only once. + pragma Assert (not Get_Visible_Flag (Decl)); + Set_Visible_Flag (Decl, True); + end Name_Visible; + + procedure Iterator_Decl (Decl : Iir; Arg : Arg_Type) + is + begin + case Get_Kind (Decl) is + when Iir_Kind_Subtype_Declaration + | Iir_Kind_Enumeration_Literal -- By use clause + | Iir_Kind_Constant_Declaration + | Iir_Kind_Signal_Declaration + | Iir_Kind_Variable_Declaration + | Iir_Kind_File_Declaration + | Iir_Kind_Object_Alias_Declaration + | Iir_Kind_Non_Object_Alias_Declaration + | Iir_Kinds_Interface_Object_Declaration + | Iir_Kind_Interface_Package_Declaration + | Iir_Kinds_Interface_Subprogram_Declaration + | Iir_Kind_Component_Declaration + | Iir_Kind_Attribute_Declaration + | Iir_Kind_Group_Template_Declaration + | Iir_Kind_Group_Declaration + | Iir_Kind_Nature_Declaration + | Iir_Kind_Free_Quantity_Declaration + | Iir_Kind_Through_Quantity_Declaration + | Iir_Kind_Across_Quantity_Declaration + | Iir_Kind_Terminal_Declaration + | Iir_Kind_Entity_Declaration + | Iir_Kind_Package_Declaration + | Iir_Kind_Package_Instantiation_Declaration + | Iir_Kind_Configuration_Declaration + | Iir_Kind_Context_Declaration + | Iir_Kinds_Concurrent_Statement + | Iir_Kinds_Sequential_Statement => + Handle_Decl (Decl, Arg); + when Iir_Kind_Procedure_Declaration + | Iir_Kind_Function_Declaration => + if not Is_Second_Subprogram_Specification (Decl) then + Handle_Decl (Decl, Arg); + end if; + when Iir_Kind_Type_Declaration => + declare + Def : constant Iir := Get_Type_Definition (Decl); + List : Iir_Flist; + El : Iir; + begin + -- Handle incomplete type declaration. + if Get_Kind (Def) = Iir_Kind_Incomplete_Type_Definition then + return; + end if; + + Handle_Decl (Decl, Arg); + + if Get_Kind (Def) = Iir_Kind_Enumeration_Type_Definition then + List := Get_Enumeration_Literal_List (Def); + for I in Flist_First .. Flist_Last (List) loop + El := Get_Nth_Element (List, I); + Handle_Decl (El, Arg); + end loop; + end if; + end; + when Iir_Kind_Anonymous_Type_Declaration => + Handle_Decl (Decl, Arg); + + declare + Def : constant Iir := Get_Type_Definition (Decl); + El : Iir; + begin + if Get_Kind (Def) = Iir_Kind_Physical_Type_Definition then + El := Get_Unit_Chain (Def); + while El /= Null_Iir loop + Handle_Decl (El, Arg); + El := Get_Chain (El); + end loop; + end if; + end; + when Iir_Kind_Interface_Type_Declaration => + Handle_Decl (Decl, Arg); + declare + El : Iir; + begin + El := Get_Interface_Type_Subprograms (Decl); + while El /= Null_Iir loop + Handle_Decl (El, Arg); + El := Get_Chain (El); + end loop; + end; + when Iir_Kind_Use_Clause + | Iir_Kind_Context_Reference => + Handle_Decl (Decl, Arg); + when Iir_Kind_Library_Clause => + Handle_Decl (Decl, Arg); +-- El := Get_Library_Declaration (Decl); +-- if El /= Null_Iir then +-- -- May be empty. +-- Handle_Decl (El, Arg); +-- end if; + + when Iir_Kind_Procedure_Body + | Iir_Kind_Function_Body => + null; + + when Iir_Kind_Package_Body => + null; + + when Iir_Kind_Attribute_Specification + | Iir_Kind_Configuration_Specification + | Iir_Kind_Disconnection_Specification => + null; + when Iir_Kinds_Signal_Attribute + | Iir_Kind_Signal_Attribute_Declaration => + null; + + when Iir_Kind_Protected_Type_Body => + -- FIXME: allowed only in debugger (if the current scope is + -- within a package body) ? + null; + + when others => + Error_Kind ("iterator_decl", Decl); + end case; + end Iterator_Decl; + + -- Handle context_clause of context reference CTXT. + procedure Add_One_Context_Reference (Ctxt : Iir) + is + Name : constant Iir := Get_Selected_Name (Ctxt); + Ent : constant Iir := Get_Named_Entity (Name); + Item : Iir; + begin + if Ent = Null_Iir or else Is_Error (Ent) then + -- Stop now in case of error. + return; + end if; + pragma Assert (Get_Kind (Ent) = Iir_Kind_Context_Declaration); + + Item := Get_Context_Items (Ent); + while Item /= Null_Iir loop + case Get_Kind (Item) is + when Iir_Kind_Use_Clause => + Add_Use_Clause (Item); + when Iir_Kind_Library_Clause => + Add_Name (Get_Library_Declaration (Item), + Get_Identifier (Item), False); + when Iir_Kind_Context_Reference => + Add_Context_Reference (Item); + when others => + Error_Kind ("add_context_reference", Item); + end case; + Item := Get_Chain (Item); + end loop; + end Add_One_Context_Reference; + + procedure Add_Context_Reference (Ref : Iir) + is + Ctxt : Iir; + begin + Ctxt := Ref; + loop + Add_One_Context_Reference (Ctxt); + Ctxt := Get_Context_Reference_Chain (Ctxt); + exit when Ctxt = Null_Iir; + end loop; + end Add_Context_Reference; + + -- Make POTENTIALLY (or not) visible DECL. + procedure Add_Name_Decl (Decl : Iir; Potentially : Boolean) is + begin + case Get_Kind (Decl) is + when Iir_Kind_Use_Clause => + if not Potentially then + Add_Use_Clause (Decl); + end if; + when Iir_Kind_Context_Reference => + pragma Assert (not Potentially); + Add_Context_Reference (Decl); + when Iir_Kind_Library_Clause => + Add_Name (Get_Library_Declaration (Decl), + Get_Identifier (Decl), Potentially); + when Iir_Kind_Anonymous_Type_Declaration => + null; + when others => + Add_Name (Decl, Get_Identifier (Decl), Potentially); + end case; + end Add_Name_Decl; + + procedure Add_Declaration is + new Iterator_Decl (Arg_Type => Boolean, Handle_Decl => Add_Name_Decl); + + procedure Iterator_Decl_List (Decl_List : Iir_List; Arg : Arg_Type) + is + Decl : Iir; + It : List_Iterator; + begin + if Decl_List = Null_Iir_List then + return; + end if; + It := List_Iterate (Decl_List); + while Is_Valid (It) loop + Decl := Get_Element (It); + Handle_Decl (Decl, Arg); + Next (It); + end loop; + end Iterator_Decl_List; + + procedure Iterator_Decl_Chain (Chain_First : Iir; Arg : Arg_Type) + is + Decl: Iir; + begin + Decl := Chain_First; + while Decl /= Null_Iir loop + Handle_Decl (Decl, Arg); + Decl := Get_Chain (Decl); + end loop; + end Iterator_Decl_Chain; + + procedure Add_Declarations_1 is new Iterator_Decl_Chain + (Arg_Type => Boolean, Handle_Decl => Add_Declaration); + + procedure Add_Declarations (Chain : Iir; Potentially : Boolean := False) + renames Add_Declarations_1; + + procedure Add_Declarations_List is new Iterator_Decl_List + (Arg_Type => Boolean, Handle_Decl => Add_Declaration); + + procedure Add_Declarations_From_Interface_Chain (Chain : Iir) + is + El : Iir; + Id : Name_Id; + begin + El := Chain; + while El /= Null_Iir loop + Id := Get_Identifier (El); + + -- The chain may be from an implicitely declared subprograms, with + -- anonymous identifiers. In that case, all interfaces are + -- anonymous and there is no need to iterate. + exit when Id = Null_Identifier; + + Add_Name (El, Id, False); + El := Get_Chain (El); + end loop; + end Add_Declarations_From_Interface_Chain; + + procedure Add_Declarations_Of_Concurrent_Statement (Parent : Iir) + is + El: Iir; + Label: Name_Id; + begin + El := Get_Concurrent_Statement_Chain (Parent); + while El /= Null_Iir loop + Label := Get_Label (El); + if Label /= Null_Identifier then + Add_Name (El, Get_Identifier (El), False); + end if; + El := Get_Chain (El); + end loop; + end Add_Declarations_Of_Concurrent_Statement; + + procedure Add_Context_Clauses (Unit : Iir_Design_Unit) is + begin + Add_Declarations (Get_Context_Items (Unit), False); + end Add_Context_Clauses; + + -- Add declarations from an entity into the current declarative region. + -- This is needed when an architecture is analysed. + procedure Add_Entity_Declarations (Entity : Iir_Entity_Declaration) + is + begin + Add_Declarations_From_Interface_Chain (Get_Generic_Chain (Entity)); + Add_Declarations_From_Interface_Chain (Get_Port_Chain (Entity)); + Add_Declarations (Get_Declaration_Chain (Entity), False); + Add_Declarations_Of_Concurrent_Statement (Entity); + end Add_Entity_Declarations; + + -- Add declarations from a package into the current declarative region. + -- (for a use clause or when a package body is analyzed) + procedure Add_Package_Declarations + (Decl: Iir_Package_Declaration; Potentially : Boolean) + is + Header : constant Iir := Get_Package_Header (Decl); + begin + -- LRM08 12.1 Declarative region + -- d) A package declaration together with the corresponding body + -- + -- GHDL: the formal generic declarations are considered to be in the + -- same declarative region as the package declarations (and therefore + -- in the same scope), even if they don't occur immediately within a + -- package declaration. + if Header /= Null_Iir then + Add_Declarations (Get_Generic_Chain (Header), Potentially); + end if; + + Add_Declarations (Get_Declaration_Chain (Decl), Potentially); + end Add_Package_Declarations; + + procedure Add_Package_Instantiation_Declarations + (Decl: Iir; Potentially : Boolean) is + begin + -- LRM08 4.9 Package instantiation declarations + -- The package instantiation declaration is equivalent to declaration of + -- a generic-mapped package, consisting of a package declaration [...] + Add_Declarations (Get_Generic_Chain (Decl), Potentially); + Add_Declarations (Get_Declaration_Chain (Decl), Potentially); + end Add_Package_Instantiation_Declarations; + + -- Add declarations from a package into the current declarative region. + -- This is needed when a package body is analysed. + procedure Add_Package_Declarations (Decl: Iir_Package_Declaration) is + begin + Add_Package_Declarations (Decl, False); + end Add_Package_Declarations; + + procedure Add_Component_Declarations (Component: Iir_Component_Declaration) + is + begin + Add_Declarations_From_Interface_Chain (Get_Generic_Chain (Component)); + Add_Declarations_From_Interface_Chain (Get_Port_Chain (Component)); + end Add_Component_Declarations; + + procedure Add_Protected_Type_Declarations + (Decl : Iir_Protected_Type_Declaration) is + begin + Add_Declarations (Get_Declaration_Chain (Decl), False); + end Add_Protected_Type_Declarations; + + procedure Extend_Scope_Of_Block_Declarations (Decl : Iir) is + begin + case Get_Kind (Decl) is + when Iir_Kind_Architecture_Body => + Add_Context_Clauses (Get_Design_Unit (Decl)); + when Iir_Kind_Block_Statement + | Iir_Kind_Generate_Statement_Body => + -- FIXME: formal, iterator ? + null; + when others => + Error_Kind ("extend_scope_of_block_declarations", Decl); + end case; + Add_Declarations (Get_Declaration_Chain (Decl), False); + Add_Declarations_Of_Concurrent_Statement (Decl); + end Extend_Scope_Of_Block_Declarations; + + procedure Use_Library_All (Library : Iir_Library_Declaration) + is + Design_File : Iir_Design_File; + Design_Unit : Iir_Design_Unit; + Library_Unit : Iir; + begin + Design_File := Get_Design_File_Chain (Library); + while Design_File /= Null_Iir loop + Design_Unit := Get_First_Design_Unit (Design_File); + while Design_Unit /= Null_Iir loop + Library_Unit := Get_Library_Unit (Design_Unit); + if Get_Kind (Library_Unit) /= Iir_Kind_Package_Body then + Add_Name (Design_Unit, Get_Identifier (Design_Unit), True); + end if; + Design_Unit := Get_Chain (Design_Unit); + end loop; + Design_File := Get_Chain (Design_File); + end loop; + end Use_Library_All; + + procedure Potentially_Add_Name (Name : Iir) is + begin + Add_Name (Name, Get_Identifier (Name), True); + end Potentially_Add_Name; + + -- LRM08 12.4 Use clauses + -- Moreover, the following declarations, if any, that occurs immediately + -- within the package denoted by the prefix of the selected name, are also + -- identifier: + procedure Use_Selected_Type_Name (Name : Iir) + is + Type_Def : constant Iir := Get_Type (Name); + Base_Type : constant Iir := Get_Base_Type (Type_Def); + begin + case Get_Kind (Base_Type) is + when Iir_Kind_Enumeration_Type_Definition => + -- LRM08 12.4 Use clauses + -- - If the type mark denotes an enumeration type of a subtype of + -- an enumeration type, the enumeration literals of the base + -- type + declare + List : constant Iir_Flist := + Get_Enumeration_Literal_List (Base_Type); + El : Iir; + begin + for I in Flist_First .. Flist_Last (List) loop + El := Get_Nth_Element (List, I); + Potentially_Add_Name (El); + end loop; + end; + when Iir_Kind_Physical_Type_Definition => + -- LRM08 12.4 Use clauses + -- - If the type mark denotes a subtype of a physical type, the + -- units of the base type + declare + El : Iir; + begin + El := Get_Unit_Chain (Base_Type); + while El /= Null_Iir loop + Potentially_Add_Name (El); + El := Get_Chain (El); + end loop; + end; + when others => + null; + end case; + + -- LRM08 12.4 Use clauses + -- - The implicit declarations of predefined operations for the type + -- that are not hidden by homographs explicitely declared immediately + -- within the package denoted by the prefix of the selected name + -- - The declarations of homographs, explicitely declared immediately + -- within the package denotes by the prefix of the selected name, + -- that hide implicit declarations of predefined operations for the + -- type + declare + Type_Decl : constant Iir := Get_Type_Declarator (Base_Type); + El : Iir; + Has_Override : Boolean; + begin + Has_Override := False; + El := Get_Chain (Type_Decl); + while El /= Null_Iir loop + if Is_Implicit_Subprogram (El) + and then Is_Operation_For_Type (El, Base_Type) + then + if Get_Visible_Flag (El) then + -- Implicit declaration EL was overriden by a user + -- declaration. Don't make it visible. + Potentially_Add_Name (El); + else + Has_Override := True; + end if; + El := Get_Chain (El); + else + exit; + end if; + end loop; + + -- Explicitely declared homograph. + if Has_Override then + while El /= Null_Iir loop + if Get_Kind (El) in Iir_Kinds_Subprogram_Declaration + and then Get_Hide_Implicit_Flag (El) + and then Is_Operation_For_Type (El, Base_Type) + then + Potentially_Add_Name (El); + end if; + El := Get_Chain (El); + end loop; + end if; + end; + end Use_Selected_Type_Name; + + -- LRM02 10.4 Use clauses + -- Each selected name in a use clause identifiers one or more declarations + -- that will potentially become directly visible. If the suffix of the + -- selected name is a simple name, a character literal, or operator + -- symbol, then the selected name identifiers only the declarations(s) of + -- that simple name, character literal, or operator symbol contained + -- within the package or library denoted by the prefix of the selected + -- name. + procedure Use_Selected_Name (Name : Iir) is + begin + case Get_Kind (Name) is + when Iir_Kind_Overload_List => + Add_Declarations_List (Get_Overload_List (Name), True); + when Iir_Kind_Error => + null; + when others => + Potentially_Add_Name (Name); + + -- LRM08 12.4 Use clauses + -- If the suffix of the selected name is a type mark, then the + -- declaration of the type or subtype denoted by the type mark + -- is identified. Moreover [...] + if (Vhdl_Std >= Vhdl_08 or else Flag_Relaxed_Rules) + and then Get_Kind (Name) in Iir_Kinds_Type_Declaration + then + Use_Selected_Type_Name (Name); + end if; + end case; + end Use_Selected_Name; + + -- LRM93 10.4 Use clauses + -- If the suffix is the reserved word ALL, then all the selected name + -- identifies all declaration that are contained within the package or + -- library denotes by te prefix of the selected name. + procedure Use_All_Names (Name: Iir) is + begin + case Get_Kind (Name) is + when Iir_Kind_Library_Declaration => + Use_Library_All (Name); + when Iir_Kind_Package_Declaration => + Add_Package_Declarations (Name, True); + when Iir_Kind_Package_Instantiation_Declaration => + Add_Package_Instantiation_Declarations (Name, True); + when Iir_Kind_Interface_Package_Declaration => + -- LRM08 6.5.5 Interface package declarations + -- Within an entity declaration, an architecture body, a + -- component declaration, or an uninstantiated subprogram or + -- package declaration that declares a given interface package, + -- the name of the given interface package denotes an undefined + -- instance of the uninstantiated package. + Add_Package_Instantiation_Declarations (Name, True); + when Iir_Kind_Error => + null; + when others => + raise Internal_Error; + end case; + end Use_All_Names; + + procedure Add_Use_Clause (Clause : Iir_Use_Clause) + is + Name : Iir; + Cl : Iir_Use_Clause; + begin + Cl := Clause; + loop + Name := Get_Selected_Name (Cl); + if Name = Null_Iir then + pragma Assert (Flags.Flag_Force_Analysis); + null; + else + if Get_Kind (Name) = Iir_Kind_Selected_By_All_Name then + Name := Get_Prefix (Name); + if not Is_Error (Name) then + Use_All_Names (Get_Named_Entity (Name)); + end if; + else + if not Is_Error (Name) then + Use_Selected_Name (Get_Named_Entity (Name)); + end if; + end if; + end if; + Cl := Get_Use_Clause_Chain (Cl); + exit when Cl = Null_Iir; + end loop; + end Add_Use_Clause; + + -- Debugging subprograms. + procedure Disp_All_Names; + pragma Unreferenced (Disp_All_Names); + + procedure Disp_Scopes; + pragma Unreferenced (Disp_Scopes); + + procedure Disp_Detailed_Interpretations (Ident : Name_Id); + pragma Unreferenced (Disp_Detailed_Interpretations); + + procedure Dump_Current_Scope; + pragma Unreferenced (Dump_Current_Scope); + + procedure Disp_Detailed_Interpretations (Ident : Name_Id) + is + Inter: Name_Interpretation_Type; + Decl : Iir; + begin + Log (Name_Table.Image (Ident)); + Log_Line (":"); + + Inter := Get_Interpretation (Ident); + while Valid_Interpretation (Inter) loop + Log (Name_Interpretation_Type'Image (Inter)); + if Is_Potentially_Visible (Inter) then + Log (" (use)"); + end if; + Log (":"); + Decl := Get_Declaration (Inter); + Log (Iir'Image (Decl)); + Log (":"); + Log (Iir_Kind'Image (Get_Kind (Decl))); + Log_Line (", loc: " & Image (Get_Location (Decl))); + if Get_Kind (Decl) in Iir_Kinds_Subprogram_Declaration then + Log_Line (" " & Disp_Subprg (Decl)); + end if; + Inter := Get_Next_Interpretation (Inter); + end loop; + end Disp_Detailed_Interpretations; + + procedure Disp_All_Interpretations + (Interpretation : Name_Interpretation_Type) + is + Inter: Name_Interpretation_Type; + begin + Inter := Interpretation; + while Valid_Interpretation (Inter) loop + Log (Name_Interpretation_Type'Image (Inter)); + Log ("."); + Log (Iir_Kind'Image (Get_Kind (Get_Declaration (Inter)))); + Inter := Get_Next_Interpretation (Inter); + end loop; + Log_Line; + end Disp_All_Interpretations; + + procedure Disp_All_Names + is + Inter: Name_Interpretation_Type; + begin + for I in 0 .. Name_Table.Last_Name_Id loop + Inter := Get_Interpretation (I); + if Valid_Interpretation (Inter) then + Log (Name_Table.Image (I)); + Log (Name_Id'Image (I)); + Log (":"); + Disp_All_Interpretations (Inter); + end if; + end loop; + Log_Line ("interprations.last = " + & Name_Interpretation_Type'Image (Interpretations.Last)); + Log_Line ("current_region_start =" + & Name_Interpretation_Type'Image (Current_Region_Start)); + end Disp_All_Names; + + procedure Dump_Interpretation (Inter : Name_Interpretation_Type) + is + Decl : Iir; + begin + Log (Name_Interpretation_Type'Image (Inter)); + if Is_Potentially_Visible (Inter) then + Log (" (use)"); + end if; + Log (": "); + Decl := Get_Declaration (Inter); + if Decl = Null_Iir then + Log_Line ("null: conflict"); + else + Log (Iir_Kind'Image (Get_Kind (Decl))); + Log_Line (", loc: " & Image (Get_Location (Decl))); + if Get_Kind (Decl) in Iir_Kinds_Subprogram_Declaration then + Log_Line (" " & Disp_Subprg (Decl)); + end if; + end if; + end Dump_Interpretation; + + procedure Dump_A_Scope (First, Last : Name_Interpretation_Type) is + begin + if First > Last then + Log_Line ("scope is empty"); + return; + end if; + + for Inter in reverse First .. Last loop + declare + Cell : Interpretation_Cell renames Interpretations.Table (Inter); + begin + Dump_Interpretation (Inter); + if Cell.Prev_Hidden then + Log (" [prev:"); + Log (Name_Interpretation_Type'Image (Cell.Prev)); + if Cell.Prev_Hidden then + Log (" hidden"); + end if; + Log_Line ("]"); + else + if Cell.Prev < First then + Log_Line (" [last in scope]"); + end if; + end if; + end; + end loop; + end Dump_A_Scope; + + procedure Dump_Current_Scope is + begin + Dump_A_Scope (Current_Region_Start, Interpretations.Last); + end Dump_Current_Scope; + + procedure Disp_Scopes is + begin + for I in reverse Scopes.First .. Scopes.Last loop + declare + S : Scope_Cell renames Scopes.Table (I); + begin + case S.Kind is + when Scope_Start => + Log ("scope_start at"); + when Scope_Region => + Log ("scope_region at"); + end case; + Log_Line (Name_Interpretation_Type'Image (S.Saved_Region_Start)); + end; + end loop; + end Disp_Scopes; +end Vhdl.Sem_Scopes; |