aboutsummaryrefslogtreecommitdiffstats
path: root/src/vhdl/vhdl-utils.ads
blob: 4ff81b011c844be140553dee21aab134441cfd45 (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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
--  Common operations on nodes.
--  Copyright (C) 2002, 2003, 2004, 2005 Tristan Gingold
--
--  This program 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 of the License, or
--  (at your option) any later version.
--
--  This program 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 this program.  If not, see <gnu.org/licenses>.
with Types; use Types;
with Vhdl.Nodes; use Vhdl.Nodes;
with PSL.Types; use PSL.Types;

package Vhdl.Utils is
   --  Get identifier of NODE as a string.
   function Image_Identifier (Node : Iir) return String;
   function Image_String_Lit (Str : Iir) return String;

   --  Return True iff N is an error node.
   function Is_Error (N : Iir) return Boolean;
   pragma Inline (Is_Error);

   --  Return True iff N is an overflow_literal node.
   function Is_Overflow_Literal (N : Iir) return Boolean;
   pragma Inline (Is_Overflow_Literal);

   --  If N is a literal and has a literal origin, return the literal origin.
   --  Otherwise return N.
   --  In other words, return the node as it was.
   function Strip_Literal_Origin (N : Iir) return Iir;

   --  Find LIT in the list of identifiers or characters LIST.
   --  Return the literal (whose name is LIT) or null_iir if not found.
   function Find_Name_In_Chain (Chain: Iir; Lit: Name_Id) return Iir;
   function Find_Name_In_Flist (List : Iir_Flist; Lit: Name_Id) return Iir;

   --  Return TRUE if EL in an element of chain CHAIN.
   function Is_In_Chain (Chain : Iir; El : Iir) return Boolean;

   --  Convert a list L to an Flist, and free L.
   function List_To_Flist (L : Iir_List) return Iir_Flist;

   --  Return a copy of the LEN first elements of L.  L is destroyed.
   function Truncate_Flist (L : Iir_Flist; Len : Natural) return Iir_Flist;

   --  Convert an operator node to a name.
   function Get_Operator_Name (Op : Iir) return Name_Id;

   -- Get the longest static prefix of EXPR.
   -- See LRM93 8.1
   function Get_Longest_Static_Prefix (Expr: Iir) return Iir;

   --  Get the prefix of NAME, ie the declaration at the base of NAME.
   --  Return NAME itself if NAME is not an object or a subelement of
   --  an object.  If WITH_ALIAS is true, continue with the alias name when an
   --  alias is found, else return the alias.
   --  FIXME: clarify when NAME is returned.
   function Get_Object_Prefix (Name: Iir; With_Alias : Boolean := True)
                              return Iir;


   --  Return TRUE if NAME is a name that designate an object (ie a constant,
   --  a variable, a signal or a file).
   function Is_Object_Name (Name : Iir) return Boolean;

   --  Return an object node if NAME designates an object (ie either is an
   --  object or a name for an object).
   --  Otherwise, returns NULL_IIR.
   --  For the definition of an object, see LRM08 6.4 Objects.
   function Name_To_Object (Name : Iir) return Iir;

   --  Return the value designated by NAME.  This is often an object, but can
   --  also be an expression like a function call or an attribute.
   function Name_To_Value (Name : Iir) return Iir;

   --  Return TRUE iff EXPR is a signal name.
   function Is_Signal_Name (Expr : Iir) return Boolean;

   --  Return TRUE iff EXPR is a quantity name.
   function Is_Quantity_Name (Expr : Iir) return Boolean;

   --  Get the interface corresponding to the formal name FORMAL.  This is
   --  always an interface, even if the formal is a name.
   function Get_Interface_Of_Formal (Formal : Iir) return Iir;

   --  Get the corresponding interface of an association while walking on
   --  associations.  ASSOC and INTER are the current association and
   --  interface (initialized to the association chain and interface chain).
   --  The function Get_Association_Interface return the interface associated
   --  to ASSOC,and Next_Association_Interface updates ASSOC and INTER.
   --
   --  Usage:
   --    Assoc := Get_xxx_Association_Chain (X);
   --    Assoc_Inter := Get_xxx_Declaration_Chain (Y);
   --    while Assoc /= Null_Iir loop
   --       Inter := Get_Association_Interface (Assoc, Assoc_Inter);
   --       ...
   --       Next_Association_Interface (Assoc, Assoc_Inter);
   --    end loop;
   --
   --  Note: This iterates over association, so unassociated interfaces are
   --   not iterated.
   function Get_Association_Interface (Assoc : Iir; Inter : Iir) return Iir;
   procedure Next_Association_Interface
     (Assoc : in out Iir; Inter : in out Iir);

   --  Return the formal of ASSOC as a named entity (either an interface
   --  declaration or indexed/sliced/selected name of it).  If there is no
   --  formal in ASSOC, return the corresponding interface INTER.
   function Get_Association_Formal (Assoc : Iir; Inter : Iir) return Iir;

   --  Return the first association in ASSOC_CHAIN for interface INTER.  This
   --  is the first in case of individual association.
   --  Return NULL_IIR if not found (not present).
   function Find_First_Association_For_Interface
     (Assoc_Chain : Iir; Inter_Chain : Iir; Inter : Iir) return Iir;

   --  Return True iff interface INTER is a (subprogram) parameter.
   function Is_Parameter (Inter : Iir) return Boolean;

   --  Return True iff parameter INTER should be copied back (for out/inout
   --  variable).
   function Is_Copyback_Parameter (Inter : Iir) return Boolean;

   --  Set/clear the Associated_XXX fields of type, package and subprogram
   --  interfaces.
   --  For set, check they were previously cleared.
   procedure Set_Interface_Associated (Inter_Chain : Iir; Assoc_Chain : Iir);
   procedure Clear_Interface_Associated (Inter_Chain : Iir);

   --  Duplicate enumeration literal LIT.
   function Copy_Enumeration_Literal (Lit : Iir) return Iir;

   --  True if EXPR can be built statically.  This is the case of literals
   --  (except overflow), and the case of some aggregates.
   --  This is different from locally static expression, particularly for
   --  aggregate: the analyzer may choose to dynamically create a locally
   --  static aggregate if it is sparse.
   function Is_Static_Construct (Expr : Iir) return Boolean;

   --  Make TARGETS depends on UNIT.
   --  UNIT must be either a design unit or a entity_aspect_entity.
   procedure Add_Dependence (Target: Iir_Design_Unit; Unit: Iir);

   --  Get the design_unit from dependency DEP.  DEP must be an element of
   --  a dependencies list.
   function Get_Unit_From_Dependence (Dep : Iir) return Iir;

   --  Clear configuration field of all component instantiation of
   --  the concurrent statements of PARENT.
   procedure Clear_Instantiation_Configuration (Parent : Iir);

   --  Free Node and its prefixes, if any.
   procedure Free_Name (Node : Iir);

   --  Free NODE and its sub-nodes.
   procedure Free_Recursive (Node : Iir; Free_List : Boolean := False);

   --  Free nodes in LIST.
   procedure Free_Recursive_List (List : Iir_List);

   --  Name of FUNC.
   function Get_Predefined_Function_Name (Func : Iir_Predefined_Functions)
     return String;

   --  Create the range_constraint node for an enumeration type.
   procedure Create_Range_Constraint_For_Enumeration_Type
     (Def : Iir_Enumeration_Type_Definition);

   --  Return the node containing the Callees_List (ie the subprogram body if
   --  SUBPRG is a subprogram spec, SUBPRG if SUBPRG is a process).
   function Get_Callees_List_Holder (Subprg : Iir) return Iir;

   --  Clear flag of TOP and all of its callees.
   procedure Clear_Seen_Flag (Top : Iir);

   --  Return the base type of ATYPE.  Will always return ATYPE if ATYPE is
   --  a proper type (and not a subtype).
   function Get_Base_Type (Atype : Iir) return Iir;

   --  Return TRUE iff DEF is an anonymous type (or subtype) definition.
   --  Note: DEF is required to be a type (or subtype) definition.
   --  Note: type (and not subtype) are never anonymous.
   function Is_Anonymous_Type_Definition (Def : Iir) return Boolean;
   pragma Inline (Is_Anonymous_Type_Definition);

   --  Return TRUE iff DEF is a fully constrained type (or subtype) definition.
   function Is_Fully_Constrained_Type (Def : Iir) return Boolean;

   --  Return TRUE iff DEF is an array type (or subtype) definition.
   function Is_Array_Type (Def : Iir) return Boolean;

   --  Return True iff OBJ can be the target of an aggregate with an others
   --  choice (cf LRM08 9.3.3.3).
   --  Return True iff object or member of it is declared to be a fully
   --  constrained subtype.
   function Is_Object_Fully_Constrained (Decl : Iir) return Boolean;
   function Is_Object_Name_Fully_Constrained (Obj : Iir) return Boolean;

   --  Return the type definition/subtype indication of NAME if NAME denotes
   --  a type or subtype name.  Otherwise, return Null_Iir;
   function Is_Type_Name (Name : Iir) return Iir;

   --  Return TRUE iff SPEC is the subprogram specification of a subprogram
   --  body which was previously declared.  In that case, the only use of SPEC
   --  is to match the body with its declaration.
   function Is_Second_Subprogram_Specification (Spec : Iir) return Boolean;

   --  Return True iif SPEC is the specification of an implicit subprogram.
   --  False for explicit subprograms.
   function Is_Implicit_Subprogram (Spec : Iir) return Boolean;
   pragma Inline (Is_Implicit_Subprogram);

   --  Return True if N is a function_declaration or an
   --  interface_function_declaration.
   function Is_Function_Declaration (N : Iir) return Boolean;
   pragma Inline (Is_Function_Declaration);

   --  Return True if N is a procedure_declaration or an
   --  interface_procedure_declaration.
   function Is_Procedure_Declaration (N : Iir) return Boolean;
   pragma Inline (Is_Procedure_Declaration);

   --  If NAME is a simple or an expanded name, return the denoted declaration.
   --  Otherwise, return NAME.
   function Strip_Denoting_Name (Name : Iir) return Iir;

   --  Build a simple name node whose named entity is REF and location LOC.
   function Build_Simple_Name (Ref : Iir; Loc : Location_Type) return Iir;
   function Build_Simple_Name (Ref : Iir; Loc : Iir) return Iir;

   --  Create a name that referenced the same named entity as NAME.
   --
   --  This is mainly used by canon, when there is a need to reference an
   --  existing name.  In some cases, it is not possible to use the name,
   --  because it is already owned.
   function Build_Reference_Name (Name : Iir) return Iir;

   --  If N is a reference_name, return the corresponding node, otherwise
   --  return N.
   function Strip_Reference_Name (N : Iir) return Iir;

   --  If SUBTYP has a resolution indication that is a function name, returns
   --  the function declaration (not the name).
   function Has_Resolution_Function (Subtyp : Iir) return Iir;

   --  Get the type of any node representing a subtype indication.  This simply
   --  skip over denoting names.
   function Get_Type_Of_Subtype_Indication (Ind : Iir) return Iir;

   --  Return True iff DEF defines a new subtype indication, not just an
   --  existing name (like a name).
   function Is_Proper_Subtype_Indication (Def : Iir) return Boolean;
   function Is_Proper_Subnature_Indication (Def : Iir) return Boolean;

   --  Return True iff the subtype indication of DECL is defined/owned by
   --  DECL.
   function Has_Owned_Subtype_Indication (Decl : Iir) return Boolean;

   --  Get the type of an index_subtype_definition or of a discrete_range from
   --  an index_constraint.
   function Get_Index_Type (Index_Type : Iir) return Iir
     renames Get_Type_Of_Subtype_Indication;

   --  Get the nature from a subnature indication.
   function Get_Nature_Of_Subnature_Indication (Ind : Iir) return Iir;

   --  Return the IDX-th index type for index subtype definition list or
   --  index_constraint INDEXES.  Return Null_Iir if IDX is out of dimension
   --  bounds, so that this function can be used to iterator over indexes of
   --  a type (or subtype).  Note that IDX starts at 0.
   function Get_Index_Type (Indexes : Iir_Flist; Idx : Natural) return Iir;

   --  Likewise but for array type or subtype ARRAY_TYPE.
   function Get_Index_Type (Array_Type : Iir; Idx : Natural) return Iir;

   --  Number of dimensions (1..n) for ARRAY_TYPE.
   function Get_Nbr_Dimensions (Array_Type : Iir) return Natural;

   --  Return True iff the all indexes of ARRAY_TYPE are locally static.
   function Are_Array_Indexes_Locally_Static (Array_Type : Iir) return Boolean;

   --  Return true if array/record bounds are locally static.  Only fully
   --  constrained records or arrays are allowed.
   --  It is possible to have non-locally static types with locally bounds (eg:
   --  a constrained array of type).
   function Are_Bounds_Locally_Static (Def : Iir) return Boolean;

   --  Return the type or subtype definition of the SUBTYP type mark.
   function Get_Denoted_Type_Mark (Subtyp : Iir) return Iir;

   --  From element declaration or element constraint EL, get the corresponding
   --  element declaration in the base record type.
   function Get_Base_Element_Declaration (El : Iir) return Iir;

   --  Append EL to the chain of owned elements of REC_TYPE.  Used only when
   --  a record_element_constraint is built.
   procedure Append_Owned_Element_Constraint (Rec_Type : Iir; El : Iir);

   --  Return true iff L and R have the same profile.
   --  L and R must be subprograms specification (or spec_body).
   function Is_Same_Profile (L, R: Iir) return Boolean;

   --  Return true iff FUNC is an operation for ATYPE.
   --
   --  LRM08 5.1 Types
   --  The set of operations of a type includes the explicitly declared
   --  subprograms that have a parameter or result of the type. The remaining
   --  operations of a type are the base operations and the predefined
   --  operations.
   function Is_Operation_For_Type (Subprg : Iir; Atype : Iir) return Boolean;

   --  From a block_specification, returns the block.
   --  Roughly speaking, this get prefix of indexed and sliced name.
   function Get_Block_From_Block_Specification (Block_Spec : Iir)
     return Iir;

   --  Wrapper around Get_Entity_Name: return the entity declaration of the
   --  entity name of DECL, or Null_Iir in case of error.
   function Get_Entity (Decl : Iir) return Iir;

   --  Wrapper around get_Configuration_Name: return the configuration
   --  declaration of ASPECT.
   function Get_Configuration (Aspect : Iir) return Iir;

   --  Return the identifier of the entity for architecture ARCH.
   function Get_Entity_Identifier_Of_Architecture (Arch : Iir) return Name_Id;

   --  Return True is component instantiation statement INST instantiate a
   --  component.
   function Is_Component_Instantiation
     (Inst : Iir_Component_Instantiation_Statement) return Boolean;

   --  Return True is component instantiation statement INST instantiate a
   --  design entity.
   function Is_Entity_Instantiation
     (Inst : Iir_Component_Instantiation_Statement) return Boolean;

   --  Get the expression of the attribute specification corresponding to the
   --  attribute name NAME.  Meaningful only for static values.
   function Get_Attribute_Name_Expression (Name : Iir) return Iir;

   --  Return the bound type of a string type, ie the type of the (first)
   --  dimension of a one-dimensional array type.
   function Get_String_Type_Bound_Type (Sub_Type : Iir) return Iir;

   --  Return left or right limit according to the direction.
   procedure Get_Low_High_Limit (Arange : Iir_Range_Expression;
                                 Low, High : out Iir);
   function Get_Low_Limit (Arange : Iir_Range_Expression) return Iir;
   function Get_High_Limit (Arange : Iir_Range_Expression) return Iir;

   --  Return TRUE iff type/subtype definition A_TYPE is an undim array.
   function Is_One_Dimensional_Array_Type (A_Type : Iir) return Boolean;

   --  Return TRUE iff unanalyzed EXPR is a range attribute.
   function Is_Range_Attribute_Name (Expr : Iir) return Boolean;

   --  Return range_expression or a range attribute from discrete range RNG.
   function Get_Range_From_Discrete_Range (Rng : Iir) return Iir;

   --  Create an array subtype from array_type or array_subtype ARR_TYPE.
   --  All fields of the returned node are filled, except the index_list.
   --  The type_staticness is set with the type staticness of the element
   --  subtype and therefore must be updated.
   --  The type_declarator field is set to null_iir.
   function Create_Array_Subtype (Arr_Type : Iir; Loc : Location_Type)
                                 return Iir_Array_Subtype_Definition;

   --  Return TRUE iff SPEC is declared inside a protected type or a protected
   --  body.
   function Is_Subprogram_Method (Spec : Iir) return Boolean;

   --  Return the protected type for method SPEC.
   function Get_Method_Type (Spec : Iir) return Iir;

   --  For Association_Element_By_Expression: return the actual.
   --  For Association_Element_Open: return the default value of the
   --    interface INTER.
   function Get_Actual_Or_Default (Assoc : Iir; Inter : Iir) return Iir;

   --  Create an error node for node ORIG.
   function Create_Error (Orig : Iir) return Iir;

   --  Create an error node for node ORIG, and set its type to ATYPE.
   --  Set its staticness to locally.
   function Create_Error_Expr (Orig : Iir; Atype : Iir) return Iir;

   --  Create an error node for node ORIG, which is supposed to be a type.
   function Create_Error_Type (Orig : Iir) return Iir;

   --  Create an error node for a name.
   function Create_Error_Name (Orig : Iir) return Iir;

   --  Extract the entity from ASPECT.
   --  Note: if ASPECT is a component declaration, returns ASPECT.
   --        if ASPECT is open, return Null_Iir;
   function Get_Entity_From_Entity_Aspect (Aspect : Iir) return Iir;

   --  Return the corresponding entity declaration from top-level configuration
   --  design unit CONFIG.
   function Get_Entity_From_Configuration (Config : Iir) return Iir;

   --  Definition from LRM08 4.8 Package bodies
   --  True if PKG (a package declaration or a package body) is not a library
   --  unit.  Can be true only for vhdl08.
   function Is_Nested_Package (Pkg : Iir) return Boolean;

   --  Definitions from LRM08 4.7 Package declarations.
   --  PKG must denote a package declaration.
   function Is_Simple_Package (Pkg : Iir) return Boolean;
   function Is_Uninstantiated_Package (Pkg : Iir) return Boolean;
   function Is_Generic_Mapped_Package (Pkg : Iir) return Boolean;

   function Is_Uninstantiated_Subprogram (Subprg : Iir) return Boolean;

   --  Return TRUE if the base name of NAME is a signal object.
   function Is_Signal_Object (Name: Iir) return Boolean;

   --  Return True IFF kind of N is K1 or K2.
   function Kind_In (N : Iir; K1, K2 : Iir_Kind) return Boolean;
   function Kind_In (N : Iir; K1, K2, K3 : Iir_Kind) return Boolean;
   pragma Inline (Kind_In);

   subtype Parameter_Index is Natural range 1 .. 4;

   --  Get/Set attribute parameter by index (for AMS attributes).
   procedure Set_Attribute_Parameter
     (Attr : Iir; N : Parameter_Index; Param : Iir);
   function Get_Attribute_Parameter
     (Attr : Iir; N : Parameter_Index) return Iir;

   --  Return the expected signature length that will be used by
   --  Get_File_Signature.
   function Get_File_Signature_Length (Def : Iir) return Natural;

   --  Store in RES the file signature for type DEF.
   --  Set the length of the buffer to OFF.
   --  Parameters are 'in out' as they are updated, so you should call this
   --  procedure with OFF = RES'First.
   procedure Get_File_Signature (Def : Iir;
                                 Res : in out String;
                                 Off : in out Natural);

   --  Like Get_Identifier but return a Name_Id for the same casing as it
   --  appears in the source file.
   --  Not useful for analysis as VHDL is case insensitive, but could be
   --  useful for error messages or tooling.
   function Get_Source_Identifier (Decl : Iir) return Name_Id;

   --  IIR wrapper around Get_HDL_Node/Set_HDL_Node.
   function Get_HDL_Node (N : PSL_Node) return Iir;
   procedure Set_HDL_Node (N : PSL_Node; Expr : Iir);
end Vhdl.Utils;