diff options
Diffstat (limited to 'sem_assocs.adb')
| -rw-r--r-- | sem_assocs.adb | 418 | 
1 files changed, 318 insertions, 100 deletions
diff --git a/sem_assocs.adb b/sem_assocs.adb index ee43e30ef..96e660875 100644 --- a/sem_assocs.adb +++ b/sem_assocs.adb @@ -26,6 +26,97 @@ with Iir_Chains; use Iir_Chains;  with Xrefs;  package body Sem_Assocs is +   function Rewrite_Non_Object_Association (Assoc : Iir; Inter : Iir) +                                           return Iir +   is +      N_Assoc : Iir; +   begin +      case Get_Kind (Inter) is +         when Iir_Kind_Interface_Package_Declaration => +            N_Assoc := Create_Iir (Iir_Kind_Association_Element_Package); +         when others => +            Error_Kind ("rewrite_non_object_association", Inter); +      end case; +      Location_Copy (N_Assoc, Assoc); +      Set_Formal (N_Assoc, Get_Formal (Assoc)); +      Set_Actual (N_Assoc, Get_Actual (Assoc)); +      Set_Chain (N_Assoc, Get_Chain (Assoc)); +      Set_Associated_Interface (N_Assoc, Inter); +      Set_Whole_Association_Flag (N_Assoc, True); +      Free_Iir (Assoc); +      return N_Assoc; +   end Rewrite_Non_Object_Association; + +   function Extract_Non_Object_Association +     (Assoc_Chain : Iir; Inter_Chain : Iir) return Iir +   is +      Inter : Iir; +      Assoc : Iir; +      --  N_Assoc : Iir; +      Prev_Assoc : Iir; +      Formal : Iir; +      Res : Iir; +   begin +      Inter := Inter_Chain; +      Assoc := Assoc_Chain; +      Prev_Assoc := Null_Iir; +      Res := Null_Iir; + +      --  Common case: only objects in interfaces. +      while Inter /= Null_Iir loop +         exit when Get_Kind (Inter) +           not in Iir_Kinds_Interface_Object_Declaration; +         Inter := Get_Chain (Inter); +      end loop; +      if Inter = Null_Iir then +         return Assoc_Chain; +      end if; + +      loop +         --  Don't try to detect errors. +         if Assoc = Null_Iir then +            return Res; +         end if; + +         Formal := Get_Formal (Assoc); +         if Formal = Null_Iir then +            --  Positional association. + +            if Inter = Null_Iir then +               --  But after a named one.  Be silent on that error. +               null; +            elsif Get_Kind (Inter) +              not in Iir_Kinds_Interface_Object_Declaration +            then +               Assoc := Rewrite_Non_Object_Association (Assoc, Inter); +            end if; +         else +            if Get_Kind (Formal) = Iir_Kind_Simple_Name then +               --  A candidate.  Search the corresponding interface. +               Inter := Find_Name_In_Chain +                 (Inter_Chain, Get_Identifier (Formal)); +               if Inter /= Null_Iir +                 and then +                 Get_Kind (Inter) not in Iir_Kinds_Interface_Object_Declaration +               then +                  Assoc := Rewrite_Non_Object_Association (Assoc, Inter); +               end if; +            end if; + +            --  No more association by position. +            Inter := Null_Iir; +         end if; + +         if Prev_Assoc = Null_Iir then +            Res := Assoc; +         else +            Set_Chain (Prev_Assoc, Assoc); +         end if; +         Prev_Assoc := Assoc; +         Assoc := Get_Chain (Assoc); +      end loop; +   end Extract_Non_Object_Association; +     --  Semantize all arguments of ASSOC_CHAIN     --  Return TRUE if no error.     function Sem_Actual_Of_Association_Chain (Assoc_Chain : Iir) @@ -49,10 +140,11 @@ package body Sem_Assocs is              Has_Named := True;              --  FIXME: check FORMAL is well composed.           elsif Has_Named then +            --  FIXME: do the check in parser.              Error_Msg_Sem ("positional argument after named argument", Assoc);              Ok := False;           end if; -         if Get_Kind (Assoc) /= Iir_Kind_Association_Element_Open then +         if Get_Kind (Assoc) = Iir_Kind_Association_Element_By_Expression then              Res := Sem_Expression_Ov (Get_Actual (Assoc), Null_Iir);              if Res = Null_Iir then                 Ok := False; @@ -136,13 +228,13 @@ package body Sem_Assocs is                 end if;                 case Get_Kind (Formal_Inter) is -                  when Iir_Kind_Signal_Interface_Declaration => +                  when Iir_Kind_Interface_Signal_Declaration =>                       --  LRM93 2.1.1                       --  In a subprogram call, the actual designator                       --  associated with a formal parameter of class                       --  signal must be a signal.                       case Get_Kind (Prefix) is -                        when Iir_Kind_Signal_Interface_Declaration +                        when Iir_Kind_Interface_Signal_Declaration                            | Iir_Kind_Signal_Declaration                            | Iir_Kind_Guard_Signal_Declaration                            | Iir_Kinds_Signal_Attribute => @@ -166,7 +258,7 @@ package body Sem_Assocs is                       end case;                       case Get_Kind (Prefix) is -                        when Iir_Kind_Signal_Interface_Declaration => +                        when Iir_Kind_Interface_Signal_Declaration =>                             Check_Parameter_Association_Restriction                               (Formal_Inter, Prefix, Assoc);                          when Iir_Kind_Guard_Signal_Declaration => @@ -198,19 +290,19 @@ package body Sem_Assocs is                          Error_Msg_Sem ("conversion are not allowed for "                                         & "signal parameters", Assoc);                       end if; -                  when Iir_Kind_Variable_Interface_Declaration => +                  when Iir_Kind_Interface_Variable_Declaration =>                       --  LRM93 2.1.1                       --  The actual designator associated with a formal of                       --  class variable must be a variable.                       case Get_Kind (Prefix) is -                        when Iir_Kind_Variable_Interface_Declaration => +                        when Iir_Kind_Interface_Variable_Declaration =>                             Check_Parameter_Association_Restriction                               (Formal_Inter, Prefix, Assoc);                          when Iir_Kind_Variable_Declaration                            | Iir_Kind_Dereference                            | Iir_Kind_Implicit_Dereference =>                             null; -                        when Iir_Kind_File_Interface_Declaration +                        when Iir_Kind_Interface_File_Declaration                            | Iir_Kind_File_Declaration =>                             --  LRM87 4.3.1.4                             --  Such an object is a member of the variable @@ -223,16 +315,16 @@ package body Sem_Assocs is                             Error_Msg_Sem                               ("variable parameter must be a variable", Assoc);                       end case; -                  when Iir_Kind_File_Interface_Declaration => +                  when Iir_Kind_Interface_File_Declaration =>                       --  LRM93 2.1.1                       --  The actual designator associated with a formal                       --  of class file must be a file.                       case Get_Kind (Prefix) is -                        when Iir_Kind_File_Interface_Declaration +                        when Iir_Kind_Interface_File_Declaration                            | Iir_Kind_File_Declaration =>                             null;                          when Iir_Kind_Variable_Declaration -                          | Iir_Kind_Variable_Interface_Declaration => +                          | Iir_Kind_Interface_Variable_Declaration =>                             if Flags.Vhdl_Std >= Vhdl_93 then                                Error_Msg_Sem ("in vhdl93, file parameter "                                               & "must be a file", Assoc); @@ -253,7 +345,7 @@ package body Sem_Assocs is                          Error_Msg_Sem ("conversion are not allowed for "                                         & "file parameters", Assoc);                       end if; -                  when Iir_Kind_Constant_Interface_Declaration => +                  when Iir_Kind_Interface_Constant_Declaration =>                       --  LRM93 2.1.1                       --  The actual designator associated with a formal of                       --  class constant must be an expression. @@ -302,8 +394,8 @@ package body Sem_Assocs is     --  Check for restrictions in LRM 1.1.1.2     --  Return FALSE in case of error.     function Check_Port_Association_Restriction -     (Formal : Iir_Signal_Interface_Declaration; -      Actual : Iir_Signal_Interface_Declaration; +     (Formal : Iir_Interface_Signal_Declaration; +      Actual : Iir_Interface_Signal_Declaration;        Assoc : Iir)       return Boolean     is @@ -368,12 +460,17 @@ package body Sem_Assocs is                       goto Found;                    end if;                 when Iir_Kind_Choice_By_Range => -                  if Eval_Int_In_Range (Eval_Pos (Index), -                                        Get_Choice_Range (Choice)) -                  then -                     --  FIXME: overlap. -                     raise Internal_Error; -                  end if; +                  declare +                     Choice_Range : constant Iir := Get_Choice_Range (Choice); +                  begin +                     if Get_Expr_Staticness (Choice_Range) = Locally +                       and then +                       Eval_Int_In_Range (Eval_Pos (Index), Choice_Range) +                     then +                        --  FIXME: overlap. +                        raise Internal_Error; +                     end if; +                  end;                 when others =>                    Error_Kind ("add_individual_assoc_index_name", Choice);              end case; @@ -419,8 +516,10 @@ package body Sem_Assocs is        Index := Get_Suffix (Formal);        --  Evaluate index. -      Index := Eval_Range (Index); -      Set_Suffix (Formal, Index); +      if Get_Expr_Staticness (Index) = Locally then +         Index := Eval_Range (Index); +         Set_Suffix (Formal, Index); +      end if;        Choice := Create_Iir (Iir_Kind_Choice_By_Range);        Location_Copy (Choice, Formal); @@ -457,7 +556,7 @@ package body Sem_Assocs is             | Iir_Kind_Slice_Name             | Iir_Kind_Selected_Element =>              Add_Individual_Association_1 (Iassoc, Get_Prefix (Formal_Object)); -         when Iir_Kinds_Interface_Declaration => +         when Iir_Kinds_Interface_Object_Declaration =>              return;           when others =>              Error_Kind ("add_individual_association_1", Formal); @@ -1178,59 +1277,142 @@ package body Sem_Assocs is        return Res;     end Extract_Out_Conversion; -   --  Associate ASSOC with interface INTERFACE -   --  This sets MATCH. -   procedure Sem_Association +   procedure Sem_Association_Open       (Assoc : Iir;        Inter : Iir;        Finish : Boolean;        Match : out Boolean)     is        Formal : Iir; -      Formal_Type : Iir; -      Actual: Iir; -      Out_Conv, In_Conv : Iir; -      Expr : Iir; -      Res_Type : Iir;        Assoc_Kind : Param_Assoc_Type;     begin        Formal := Get_Formal (Assoc); -      --  Handle open association. -      if Get_Kind (Assoc) = Iir_Kind_Association_Element_Open then -         if Formal /= Null_Iir then -            Assoc_Kind := Sem_Formal (Formal, Inter); -            if Assoc_Kind = None then +      if Formal /= Null_Iir then +         Assoc_Kind := Sem_Formal (Formal, Inter); +         if Assoc_Kind = None then +            Match := False; +            return; +         end if; +         Set_Whole_Association_Flag (Assoc, Assoc_Kind = Whole); +         if Finish then +            Sem_Name (Formal); +            Formal := Finish_Sem_Name (Formal); +            Set_Formal (Assoc, Formal); +            if Get_Kind (Formal) in Iir_Kinds_Denoting_Name +              and then Is_Error (Get_Named_Entity (Formal)) +            then                 Match := False;                 return;              end if; -            Set_Whole_Association_Flag (Assoc, Assoc_Kind = Whole); -            if Finish then -               Sem_Name (Formal); -               Formal := Finish_Sem_Name (Formal); -               Set_Formal (Assoc, Formal); -               if Get_Kind (Formal) in Iir_Kinds_Denoting_Name -                 and then Is_Error (Get_Named_Entity (Formal)) -               then -                  Match := False; -                  return; -               end if; -               --  LRM 4.3.3.2  Associations lists -               --  It is an error if an actual of open is associated with a -               --  formal that is associated individually. -               if Assoc_Kind = Individual then -                  Error_Msg_Sem ("cannot associate individually with open", -                                 Assoc); -               end if; +            --  LRM 4.3.3.2  Associations lists +            --  It is an error if an actual of open is associated with a +            --  formal that is associated individually. +            if Assoc_Kind = Individual then +               Error_Msg_Sem ("cannot associate individually with open", +                              Assoc);              end if; -         else -            Set_Whole_Association_Flag (Assoc, True);           end if; -         Match := True; +      else +         Set_Whole_Association_Flag (Assoc, True); +      end if; +      Match := True; +   end Sem_Association_Open; + +   procedure Sem_Association_Package +     (Assoc : Iir; +      Inter : Iir; +      Finish : Boolean; +      Match : out Boolean) +   is +      Formal : constant Iir := Get_Formal (Assoc); +      Actual : Iir; +      Package_Inter : Iir; +   begin +      if not Finish then +         Match := Get_Associated_Interface (Assoc) = Inter; +         return; +      end if; + +      --  Always match (as this is a generic association, there is no +      --  need to resolve overload). +      pragma Assert (Get_Associated_Interface (Assoc) = Inter); +      Match := True; + +      if Formal /= Null_Iir then +         pragma Assert (Get_Kind (Formal) = Iir_Kind_Simple_Name); +         pragma Assert (Get_Identifier (Formal) = Get_Identifier (Inter)); +         Set_Named_Entity (Formal, Inter); +         Set_Base_Name (Formal, Inter); +      end if; + +      --  Analyze actual. +      Actual := Get_Actual (Assoc); +      Actual := Sem_Denoting_Name (Actual); +      Set_Actual (Assoc, Actual); + +      Actual := Get_Named_Entity (Actual); +      if Is_Error (Actual) then +         return; +      end if; + +      --  LRM08 6.5.7.2 Generic map aspects +      --  An actual associated with a formal generic package in a +      --  generic map aspect shall be the name that denotes an instance +      --  of the uninstantiated package named in the formal generic +      --  package declaration [...] +      if Get_Kind (Actual) /= Iir_Kind_Package_Instantiation_Declaration then +         Error_Msg_Sem +           ("actual of association is not a package instantiation", Assoc); +         return; +      end if; + +      Package_Inter := +        Get_Named_Entity (Get_Uninstantiated_Package_Name (Inter)); +      if Get_Named_Entity (Get_Uninstantiated_Package_Name (Actual)) +        /= Package_Inter +      then +         Error_Msg_Sem +           ("actual package name is not an instance of interface package", +            Assoc);           return;        end if; +      --  LRM08 6.5.7.2 Generic map aspects +      --  b) If the formal generic package declaration includes an interface +      --     generic map aspect in the form that includes the box (<>) symbol, +      --     then the instantiaed package denotes by the actual may be any +      --     instance of the uninstantiated package named in the formal +      --     generic package declaration. +      if Get_Generic_Map_Aspect_Chain (Inter) = Null_Iir then +         null; +      else +         --  Other cases not yet handled. +         raise Internal_Error; +      end if; + +      return; +   end Sem_Association_Package; + +   --  Associate ASSOC with interface INTERFACE +   --  This sets MATCH. +   procedure Sem_Association_By_Expression +     (Assoc : Iir; +      Inter : Iir; +      Finish : Boolean; +      Match : out Boolean) +   is +      Formal : Iir; +      Formal_Type : Iir; +      Actual: Iir; +      Out_Conv, In_Conv : Iir; +      Expr : Iir; +      Res_Type : Iir; +      Assoc_Kind : Param_Assoc_Type; +   begin +      Formal := Get_Formal (Assoc); +        --  Pre-semantize formal and extract out conversion.        if Formal /= Null_Iir then           Assoc_Kind := Sem_Formal (Formal, Inter); @@ -1252,7 +1434,7 @@ package body Sem_Assocs is        --  Extract conversion from actual.        Actual := Get_Actual (Assoc);        In_Conv := Null_Iir; -      if Get_Kind (Inter) /= Iir_Kind_Constant_Interface_Declaration then +      if Get_Kind (Inter) /= Iir_Kind_Interface_Constant_Declaration then           case Get_Kind (Actual) is              when Iir_Kind_Function_Call =>                 Expr := Get_Parameter_Association_Chain (Actual); @@ -1403,6 +1585,26 @@ package body Sem_Assocs is              end if;           end if;        end if; +   end Sem_Association_By_Expression; + +      --  Associate ASSOC with interface INTERFACE +   --  This sets MATCH. +   procedure Sem_Association +     (Assoc : Iir; Inter : Iir; Finish : Boolean; Match : out Boolean) is +   begin +      case Get_Kind (Assoc) is +         when Iir_Kind_Association_Element_Open => +            Sem_Association_Open (Assoc, Inter, Finish, Match); + +         when Iir_Kind_Association_Element_Package => +            Sem_Association_Package (Assoc, Inter, Finish, Match); + +         when Iir_Kind_Association_Element_By_Expression => +            Sem_Association_By_Expression (Assoc, Inter, Finish, Match); + +         when others => +            Error_Kind ("sem_assocation", Assoc); +      end case;     end Sem_Association;     procedure Sem_Association_Chain @@ -1609,7 +1811,7 @@ package body Sem_Assocs is           return;        end if; -      --  LRM 8.6 Procedure Call Statement +      --  LRM93 8.6 Procedure Call Statement        --  For each formal parameter of a procedure, a procedure call must        --  specify exactly one corresponding actual parameter.        --  This actual parameter is specified either explicitly, by an @@ -1617,7 +1819,7 @@ package body Sem_Assocs is        --  list, or in the absence of such an association element, by a default        --  expression (see Section 4.3.3.2). -      --  LRM 7.3.3 Function Calls +      --  LRM93 7.3.3 Function Calls        --  For each formal parameter of a function, a function call must        --  specify exactly one corresponding actual parameter.        --  This actual parameter is specified either explicitly, by an @@ -1625,61 +1827,77 @@ package body Sem_Assocs is        --  list, or in the absence of such an association element, by a default        --  expression (see Section 4.3.3.2). -      --  LRM 1.1.1.2 +      --  LRM93 1.1.1.2 / LRM08 6.5.6.3 Port clauses        --  A port of mode IN may be unconnected or unassociated only if its        --  declaration includes a default expression.        --  It is an error if a port of any mode other than IN is unconnected        --  or unassociated and its type is an unconstrained array type. +      --  LRM08 6.5.6.2 Generic clauses +      --  It is an error if no such actual [instantiated package] is specified +      --  for a given formal generic package (either because the formal generic +      --  is unassociated or because the actual is OPEN). +        Inter := Interface_Chain;        Pos := 0;        while Inter /= Null_Iir loop -         if Arg_Matched (Pos) <= Open -           and then Get_Default_Value (Inter) = Null_Iir -         then -            case Missing is -               when Missing_Parameter -                 | Missing_Generic => -                  if Finish then -                     Error_Msg_Sem ("no actual for " & Disp_Node (Inter), Loc); -                  end if; -                  Match := False; -                  return; -               when Missing_Port => -                  case Get_Mode (Inter) is -                     when Iir_In_Mode => -                        if not Finish then -                           raise Internal_Error; -                        end if; -                        Error_Msg_Sem (Disp_Node (Inter) -                                       & " of mode IN must be connected", Loc); -                        Match := False; -                        return; -                     when Iir_Out_Mode -                       | Iir_Linkage_Mode -                       | Iir_Inout_Mode -                       | Iir_Buffer_Mode => -                        if not Finish then -                           raise Internal_Error; -                        end if; -                        if not Is_Fully_Constrained_Type (Get_Type (Inter)) -                        then -                           Error_Msg_Sem -                             ("unconstrained " & Disp_Node (Inter) -                              & " must be connected", Loc); +         if Arg_Matched (Pos) <= Open then +            case Get_Kind (Inter) is +               when Iir_Kinds_Interface_Object_Declaration => +                  if Get_Default_Value (Inter) = Null_Iir then +                     case Missing is +                        when Missing_Parameter +                          | Missing_Generic => +                           if Finish then +                              Error_Msg_Sem +                                ("no actual for " & Disp_Node (Inter), Loc); +                           end if;                             Match := False;                             return; -                        end if; -                     when Iir_Unknown_Mode => -                        raise Internal_Error; -                  end case; -               when Missing_Allowed => -                  null; +                        when Missing_Port => +                           case Get_Mode (Inter) is +                              when Iir_In_Mode => +                                 if not Finish then +                                    raise Internal_Error; +                                 end if; +                                 Error_Msg_Sem +                                   (Disp_Node (Inter) +                                      & " of mode IN must be connected", Loc); +                                 Match := False; +                                 return; +                              when Iir_Out_Mode +                                | Iir_Linkage_Mode +                                | Iir_Inout_Mode +                                | Iir_Buffer_Mode => +                                 if not Finish then +                                    raise Internal_Error; +                                 end if; +                                 if not Is_Fully_Constrained_Type +                                   (Get_Type (Inter)) +                                 then +                                    Error_Msg_Sem +                                      ("unconstrained " & Disp_Node (Inter) +                                         & " must be connected", Loc); +                                    Match := False; +                                    return; +                                 end if; +                              when Iir_Unknown_Mode => +                                 raise Internal_Error; +                           end case; +                        when Missing_Allowed => +                           null; +                     end case; +                  end if; +               when Iir_Kind_Interface_Package_Declaration => +                  Error_Msg_Sem +                    (Disp_Node (Inter) & " must be associated", Loc); +                  Match := False; +               when others => +                  Error_Kind ("sem_association_chain", Inter);              end case;           end if;           Inter := Get_Chain (Inter);           Pos := Pos + 1;        end loop; -      return;     end Sem_Association_Chain;  end Sem_Assocs;  | 
