aboutsummaryrefslogtreecommitdiffstats
path: root/sem_expr.ads
blob: 3304923c7c1a72646edde2c6b8422c5aa6cf064f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
--  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 Types; use Types;
with Iirs; use Iirs;

package Sem_Expr is
   -- Set semantic to EXPR.
   --  Replace simple_name with the referenced node,
   --  Set type to nodes,
   --  Resolve overloading

   Deferred_Constant_Allowed : Boolean := False;

   -- Semantize an expression (other than a range) with a possible overloading.
   -- Sem_expression_ov (and therefore sem_expression) must be called *once*
   -- for each expression node with A_TYPE1 not null and at most *once* with
   -- A_TYPE1 null.
   --
   -- When A_TYPE1 is null, sem_expression_ov find all possible types
   -- of the expression.  If there is only one possible type (ie, overloading
   -- is non-existant or solved), then the type of the expression is set,
   -- and the node is completly semantized.  Sem_expression_ov must not
   -- be called for such a node.
   -- If there is several possible types (ie overloaded), then the type is
   -- set with a list of overload.  To finishes the semantisation,
   -- sem_expression_ov must be called again with A_TYPE1 set to the
   -- expected type.
   --
   -- If A_TYPE1 is set, sem_expression_ov must finishes the semantisation
   -- of the expression, and set its type, which is not necessary a base type.
   -- A_TYPE1 must be a base type.
   --
   -- In case of error, it displays a message and return null.
   -- In case of success, it returns the semantized expression, which can
   -- be different from EXPR (eg, a character literal is transformed into an
   -- enumeration literal).
   function Sem_Expression_Ov (Expr: Iir; A_Type1: Iir) return Iir;

   -- If A_TYPE is not null, then EXPR must be of type A_TYPE.
   -- Return null in case of error.
   function Sem_Expression (Expr: Iir; A_Type: Iir) return Iir;

   --  Same as Sem_Expression, but also implicitly choose an universal type
   --  if overloaded.
   function Sem_Expression_Universal (Expr : Iir) return Iir;

   --  Same as Sem_Expression but specialized for a case expression.
   --  (Handle specific overloading rules).
   function Sem_Case_Expression (Expr : Iir) return Iir;

   --  Sem COND as a condition.
   --  In VHDL08, this follows 9.2.9 Condition operator.
   --  In VHDL87 and 93, type of COND must be a boolean.
   --  A check is made that COND can be read.
   function Sem_Condition (Cond : Iir) return Iir;

   --  Check EXPR can be read.
   procedure Check_Read (Expr : Iir);

   --  Check EXPR can be updated.
   procedure Check_Update (Expr : Iir);

   --  Check the type of EXPR can be implicitly converted to TARG_TYPE, ie
   --  if TARG_TYPE is a constrained array subtype, number of elements matches.
   --  Return FALSE in case of error.
   --  If TARG_TYPE or EXPR is NULL_IIR, silently returns TRUE.
   function Check_Implicit_Conversion (Targ_Type : Iir; Expr : Iir)
                                      return Boolean;

   -- For a procedure call, A_TYPE must be null.
   function Sem_Subprogram_Call (Expr: Iir; A_Type: Iir)
     return Iir;

   --  If EXPR is a node for an expression, then return EXPR.
   --  Otherwise, emit an error message using LOC as location
   --   and return NULL_IIR.
   --  If EXPR is NULL_IIR, NULL_IIR is silently returned.
   function Check_Is_Expression (Expr : Iir; Loc : Iir) return Iir;

   --  Semantize a procedure_call or a concurrent_procedure_call_statement.
   procedure Sem_Procedure_Call (Call : Iir_Procedure_Call; Stmt : Iir);

   --  Semantize a range.  If ANY_DIR is true, the range can't be a
   --  null range (slice vs subtype -- used in static evaluation).
   function Sem_Range_Expression (Expr: Iir; A_Type: Iir; Any_Dir : Boolean)
     return Iir;

   --  Semantize a discrete range.  If ANY_DIR is true, the range can't be a
   --  null range (slice vs subtype -- used in static evaluation).
   function Sem_Discrete_Range_Expression
     (Expr: Iir; A_Type: Iir; Any_Dir: Boolean) return Iir;
   function Get_Discrete_Range_Staticness (Expr : Iir) return Iir_Staticness;

   --  Semantize a discrete range and convert to integer if both bounds are
   --  universal integer types, according to rules of LRM 3.2.1.1
   function Sem_Discrete_Range_Integer (Expr: Iir) return Iir;

   --  Convert a parenthesis_name to a slice_name or an index_name, according
   --  to the suffix expression.
   --  This is used in sem by generates.
   --function Sem_Parenthesis_Name (Name : Iir_Parenthesis_Name) return Iir;

   -- Transform LIT into a physical_literal.
   -- LIT can be either a not semantized physical literal or
   --  a simple name that is a physical unit.  In the later case, a physical
   --  literal is created.
   function Sem_Physical_Literal (Lit: Iir) return Iir;

   --  CHOICES_LIST is a list of choices (none, expression, range, list or
   --    others).
   --  If IS_SUB_RANGE is true, then SUB_TYPE may not be fully convered,
   --    otherwise, SUB_TYPE must be fully covered.
   --    This is used when the subtype of an aggregate must be determined.
   --  SUB_TYPE is the discrete subtype.
   --  Emit a message if:
   --  * the SUB_TYPE is not fully covered by the choices
   --  * the choices are not mutually exclusif (an element is present twice)
   --  * OTHERS is not the last choice, or is present several times.
   --
   --  If there is at least one named choice, LOW and HIGH are set with the
   --  lowest and highest index.
   --  If LOW and HIGH are set, they are locally static.
   --
   --  Unidimensional strings are not handled here but by
   --  sem_string_choices_range.
   --
   --  TODO:
   --  * be smarter if only positional choices (do not create the list).
   --  * smarter messages.
   procedure Sem_Choices_Range
     (Choice_Chain : in out Iir;
      Sub_Type : Iir;
      Is_Sub_Range : Boolean;
      Is_Case_Stmt : Boolean;
      Loc : Location_Type;
      Low : out Iir;
      High : out Iir);

   --  Semantize CHOICE_LIST when the choice expression SEL is of a
   --  one-dimensional character array type.
   procedure Sem_String_Choices_Range (Choice_Chain : Iir; Sel : Iir);

   -- LEFT are RIGHT must be really a type (not a subtype).
   function Are_Basetypes_Compatible (Left: Iir; Right: Iir)
     return Boolean;

   --  Return TRUE iif types of LEFT and RIGHT are compatible.
   function Are_Nodes_Compatible (Left: Iir; Right: Iir)
     return Boolean;

   --  Return TRUE iff the type of EXPR is compatible with A_TYPE
   function Is_Expr_Compatible (A_Type : Iir; Expr : Iir) return Boolean;

   --  LIST1, LIST2 are either a type node or an overload list of types.
   --  Return THE type which is compatible with LIST1 are LIST2.
   --  Return null_iir if there is no such type or if there are several types.
   function Search_Compatible_Type (List1, List2 : Iir) return Iir;
end Sem_Expr;