aboutsummaryrefslogtreecommitdiffstats
path: root/cparser/Cutil.mli
blob: 17eb22076d309307b99a0d625400b58886f83af2 (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
(* *********************************************************************)
(*                                                                     *)
(*              The Compcert verified compiler                         *)
(*                                                                     *)
(*          Xavier Leroy, INRIA Paris-Rocquencourt                     *)
(*                                                                     *)
(*  Copyright Institut National de Recherche en Informatique et en     *)
(*  Automatique.  All rights reserved.  This file is distributed       *)
(*  under the terms of the GNU Lesser General Public License as        *)
(*  published by the Free Software Foundation, either version 2.1 of   *)
(*  the License, or  (at your option) any later version.               *)
(*  This file is also distributed under the terms of the               *)
(*  INRIA Non-Commercial License Agreement.                            *)
(*                                                                     *)
(* *********************************************************************)

(* Useful functions to manipulate C abstract syntax *)

open C

(* Sets and maps over identifiers *)
module IdentSet : Set.S with type elt = ident
module IdentMap : Map.S with type key = ident

(* Typedef handling *)
val unroll : Env.t -> typ -> typ
  (* Expand typedefs at head of type.  Returned type is not [TNamed]. *)

(* Attributes *)

val add_attributes : attributes -> attributes -> attributes
  (* Union of two sets of attributes *)
val remove_attributes : attributes -> attributes -> attributes
  (* Difference [attr1 \ attr2] between two sets of attributes *)
val incl_attributes : attributes -> attributes -> bool
  (* Check that first set of attributes is a subset of second set. *)
val alignas_attribute : attributes -> int
  (* Extract the value of the [_Alignas] and [attribute((aligned(N)))]
     attributes, if any.
     Return 0 if none, a (positive) power of two alignment if some. *)
val packing_parameters : attributes -> int * int * bool
  (* Extract the value of the [__packed__] attributes, if any.
     Return a triple
     (maximum field alignment, minimum struct alignment, byte swapping).
     Alignments of 0 mean default alignment. *)
val find_custom_attributes : string list -> attributes -> attr_arg list list
  (* Extract arguments of custom [Attr] attributes whose names appear
     in the given list of names. *)
val remove_custom_attributes : string list -> attributes -> attributes
  (* Remove all [Attr] attributes whose names appear
     in the given list of names. *)
val attributes_of_type : Env.t -> typ -> attributes
  (* Return the attributes of the given type, expanding typedefs if needed. *)
val attributes_of_type_no_expand : typ -> attributes
  (* Return the attributes of the given type, without expanding typedefs. *)
val add_attributes_type : attributes -> typ -> typ
  (* Add the given set of attributes to those of the given type. *)
val remove_attributes_type : Env.t -> attributes -> typ -> typ
  (* Remove the given set of attributes to those of the given type. *)
val erase_attributes_type : Env.t -> typ -> typ
  (* Erase the attributes of the given type. *)
val change_attributes_type : Env.t -> (attributes -> attributes) -> typ -> typ
  (* Apply the given function to the top-level attributes of the given type *)
val has_std_alignas :  Env.t -> typ -> bool
  (* Do the attributes of the type contain the C11 _Alignas attribute *)

type attribute_class =
  | Attr_object         (* Attribute applies to the object being declared
                          (function, global variable, local variable)  *)
  | Attr_name           (* Attribute applies to the name being declared
                          (object, struct/union member, struct/union/enum tag *)
  | Attr_type           (* Attribute applies to types *)
  | Attr_struct         (* Attribute applies to struct, union and enum *)
  | Attr_function       (* Attribute applies to function types and decls *)
  | Attr_unknown        (* Not a declared attribute *)

val declare_attribute: string -> attribute_class -> unit
val declare_attributes: (string * attribute_class) list -> unit
  (* Register the given custom attribute names with the given classes. *)
val class_of_attribute: attribute -> attribute_class
  (* Return the class of the given attribute.  Standard attributes
     have class [Attr_type].  Custom attributes have the class that
     was given to them using [declare_attribute], or [Attr_unknown]
     if not declared. *)
val name_of_attribute: attribute -> string
  (* Name for printing an attribute *)
val attr_inherited_by_members: attribute -> bool
  (* Is an attribute of a composite inherited by members of the composite? *)


val strip_attributes_type: typ -> attribute list -> typ
  (* Remove all attributes from the given type that are not contained in the list *)
val strip_last_attribute: typ -> attribute option * typ
  (* Remove the last top level attribute and return it *)


(* Type compatibility *)

type attr_handling =
  | AttrCompat
  | AttrIgnoreTop
  | AttrIgnoreAll

val compatible_types : attr_handling -> Env.t -> typ -> typ -> bool
  (* Check that the two given types are compatible.
     The attributes in the types are compared according to the first argument:
- [AttrCompat]: the types must have the same standard attributes
    ([const], [volatile], [restrict]) but may differ on custom attributes.
- [AttrIgnoreTop]: the top-level attributes of the two types are ignored,
    but attributes of e.g. types of pointed objects (for pointer types)
    are compared as per [AttrCompat].
- [AttrIgnoreAll]: recursively ignore the attributes in the two types. *)
val combine_types : attr_handling -> Env.t -> typ -> typ -> typ option
  (* Like [compatible_types], but if the two types are compatible,
     return the most precise type compatible with both.
     The attributes are compared according to the first argument,
     with the same meaning as for [compatible_types].
     When two sets of attributes are compatible, the result of
     [combine_types] carries the union of these two sets of attributes. *)
val equal_types : Env.t -> typ -> typ -> bool
   (* Check that the two given types are equal up to typedef use *)

(* Size and alignment *)

val sizeof : Env.t -> typ -> int option
  (* Return the size alignment of the given type, in bytes.
     Machine-dependent. [None] is returned if the type is incomplete. *)
val alignof : Env.t -> typ -> int option
  (* Return the natural alignment of the given type, in bytes.
     Machine-dependent. [None] is returned if the type is incomplete. *)
val incomplete_type : Env.t -> typ -> bool
  (* Return true if the given type is incomplete, e.g.
     declared but not defined struct or union, or array type  without a size. *)
val sizeof_ikind: ikind -> int
  (* Return the size of the given integer kind. *)
val sizeof_fkind: fkind -> int
  (* Return the size of the given float kind. *)

(* Computing composite_info records *)

val composite_info_decl:
  struct_or_union -> attributes -> Env.composite_info
val composite_info_def:
  Env.t -> struct_or_union -> attributes -> field list -> Env.composite_info
val struct_layout:
  Env.t -> attributes -> field list -> (string * int) list
val offsetof:
  Env.t -> typ -> field -> int
(* Compute the offset of a struct member *)
val cautious_mul: int64 -> int -> int option
(* Overflow-avoiding multiplication of an int64 and an int, with
   result in type int. *)

(* Type classification functions *)

val is_void_type : Env.t -> typ -> bool
  (* Is type [void]? *)
val is_integer_type : Env.t -> typ -> bool
  (* Is type integer? *)
val is_float_type : Env.t -> typ -> bool
  (* Is type float *)
val is_arith_type : Env.t -> typ -> bool
  (* Is type integer or float? *)
val is_pointer_type : Env.t -> typ -> bool
  (* Is type a pointer type? *)
val is_scalar_type : Env.t -> typ -> bool
  (* Is type integer, float or pointer? *)
val is_composite_type : Env.t -> typ -> bool
  (* Is type a struct or union? *)
val is_array_type : Env.t -> typ -> bool
  (* Is type an array type? *)
val is_function_type : Env.t -> typ -> bool
  (* Is type a function type? (not pointer to function) *)
val is_function_pointer_type : Env.t -> typ -> bool
  (* Is type a pointer to function type? *)
val is_anonymous_composite : typ -> bool
  (* Is type an anonymous composite? *)
val is_anonymous_type : typ -> bool
  (* Is the type an anonymous composite or enum *)
val is_qualified_array : typ -> bool
  (* Does the type contain a qualified array type (e.g. int[const 5])? *)
val pointer_arithmetic_ok : Env.t -> typ -> bool
  (* Is the type [*ty] appropriate for pointer arithmetic?
     [ty] must not be void, nor a function type, nor an incomplete type. *)
val is_signed_ikind : ikind -> bool
  (* Return true if the given integer kind is a signed type. *)
val unsigned_ikind_of : ikind -> ikind
  (* Return the unsigned integer kind corresponding to the given
     integer kind. *)
val signed_ikind_of : ikind -> ikind
  (* Return the signed integer kind corresponding to the given
     integer kind. *)
val integer_rank : ikind -> int
  (* Order integer kinds from smaller to bigger *)
val float_rank : fkind -> int
  (* Order float kinds from smaller to bigger *)

(* Usual conversions over types *)

val pointer_decay : Env.t -> typ -> typ
  (* Transform (decay) array and function types to pointer types. *)
val unary_conversion : Env.t -> typ -> typ
  (* The usual unary conversions:
       small integer types are promoted to [int]
       array and function types decay *)
val binary_conversion : Env.t -> typ -> typ -> typ
  (* The usual binary conversions.  Applies only to arithmetic types.
     Return the arithmetic type to which both operands of the binop
     are converted. *)
val argument_conversion : Env.t -> typ -> typ
  (* Conversion applied to the argument of a prototyped function.
     Equivalent to [pointer_decay]. *)
val default_argument_conversion : Env.t -> typ -> typ
  (* Conversion applied to the argument of a nonprototyped or variadic
     function.  Like unary conversion, plus [float] becomes [double]. *)

(* Special types *)
val enum_ikind : ikind
  (* Integer kind for enum values.  Always [IInt]. *)
val wchar_ikind : unit -> ikind
  (* Integer kind for wchar_t type. *)
val size_t_ikind : unit -> ikind
  (* Integer kind for size_t type.  Unsigned. *)
val ptr_t_ikind : unit -> ikind
  (* Integer kind for ptr_t type.  Smallest unsigned kind large enough
     to contain a pointer without information loss. *)
val ptrdiff_t_ikind : unit -> ikind
  (* Integer kind for ptrdiff_t type.  Smallest signed kind large enough
     to contain the difference between two pointers. *)

(* Helpers for type-checking *)

val type_of_constant : constant -> typ
  (* Return the type of the given constant. *)
val type_of_member : Env.t -> field -> typ
  (* Return the type of accessing the given field [fld].
     Normally it's [fld.fld_type] but there is a special case for
     small unsigned bitfields. *)
val is_call_to_fun : exp -> string -> bool
  (* Test whether the caller is the given function *)
val is_debug_stmt : stmt -> bool
  (* Is the given statement a call to debug builtin? *)
val is_literal_0 : exp -> bool
  (* Is the given expression the integer literal "0"?  *)
val is_lvalue : exp -> bool
  (* Is the given expression a l-value? *)
val is_modifiable_lvalue : Env.t -> exp -> bool
  (* Is the given expression a modifiable l-value? *)
val valid_assignment : Env.t -> exp -> typ -> bool
  (* Check that an assignment of the given expression to a l-value of
     the given type is allowed. *)
val valid_cast : Env.t -> typ -> typ -> bool
  (* Check that a cast from the first type to the second is allowed. *)
val int_pointer_conversion : Env.t -> typ -> typ -> bool
  (* Check that the cast from tfrom to tto is an integer to pointer
     conversion *)
val fundef_typ: fundef -> typ
  (* Return the function type for the given function definition. *)
val int_representable: int64 -> int -> bool -> bool
  (* Is the given int64 representable with the given number of bits and
     signedness? *)
val field_of_dot_access: Env.t -> typ -> string -> field
  (* Return the field info for a [x.field] access *)
val field_of_arrow_access: Env.t -> typ -> string -> field
  (* Return the field info for a [x->field] access *)
val valid_array_size: Env.t -> typ -> int64 -> bool
  (* Test whether the array size fits in half of the address space *)
val is_volatile_variable: Env.t -> exp -> bool
  (* Test whether the expression is an access to a volatile variable *)
val is_bitfield: Env.t -> exp -> bool
  (* Test whether the expression is a bit-field *)
val contains_flex_array_mem : Env.t  -> typ -> bool
  (* Is this a struct with a flexible array member *)

(* Constructors *)

val intconst : int64 -> ikind -> exp
  (* Build expression for given integer constant. *)
val floatconst0 : exp
  (* Build expression for (double)0. *)
val nullconst : exp
  (* Expression for [(void * ) 0] *)
val eaddrof : exp -> exp
  (* Expression for [&e] *)
val ecast : typ -> exp -> exp
  (* Expression for [(ty)e] *)
val eassign : exp -> exp -> exp
  (* Expression for [e1 = e2] *)
val ecomma :  exp -> exp -> exp
  (* Expression for [e1, e2] *)
val ecommalist :  exp list -> exp -> exp
  (* Expression for [e1, ..., eN, e] *)
val sskip: stmt
  (* The [skip] statement.  No location. *)
val sseq : location -> stmt -> stmt -> stmt
  (* Return the statement [s1; s2], optimizing the cases
     where [s1] or [s2] is [skip], or [s2] is a block. *)
val sassign : location -> exp -> exp -> stmt
  (* Return the statement [exp1 = exp2;] *)

(* Locations *)

val no_loc: location
  (* Denotes an unknown location. *)
val printloc: out_channel -> location -> unit
  (* Printer for locations (for Printf) *)
val formatloc: Format.formatter -> location -> unit
  (* Printer for locations (for Format) *)

(* Initializers *)
exception No_default_init
  (* Raised if no default initilaizer exists *)

val default_init: Env.t -> typ -> init
  (* Return a default initializer for the given type
     (with zero numbers, null pointers, etc). *)

(* Substitution of variables by expressions *)

val subst_expr: exp IdentMap.t -> exp -> exp
val subst_init: exp IdentMap.t -> init -> init
val subst_decl: exp IdentMap.t -> decl -> decl
val subst_stmt: exp IdentMap.t -> stmt -> stmt