File: CType.ml

package info (click to toggle)
herdtools7 7.58-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 19,732 kB
  • sloc: ml: 128,583; ansic: 3,827; makefile: 670; python: 407; sh: 212; awk: 14
file content (231 lines) | stat: -rw-r--r-- 7,544 bytes parent folder | download
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
(****************************************************************************)
(*                           the diy toolsuite                              *)
(*                                                                          *)
(* Jade Alglave, University College London, UK.                             *)
(* Luc Maranget, INRIA Paris-Rocquencourt, France.                          *)
(*                                                                          *)
(* Copyright 2014-present Institut National de Recherche en Informatique et *)
(* en Automatique and the authors. All rights reserved.                     *)
(*                                                                          *)
(* This software is governed by the CeCILL-B license under French law and   *)
(* abiding by the rules of distribution of free software. You can use,      *)
(* modify and/ or redistribute the software under the terms of the CeCILL-B *)
(* license as circulated by CEA, CNRS and INRIA at the following URL        *)
(* "http://www.cecill.info". We also give a copy in LICENSE.txt.            *)
(****************************************************************************)

open Printf

type base = string

type t =
  | Base of base
  | Volatile of t
  | Const of t
  | Atomic of t
  | Pointer of t
(** limited arrays *)
  | Array of base * int

let void = Base "void"
let voidstar = Pointer void
let word = Base "int"
let quad = Base "int64_t"
let int32x4_t = Base "int32x4_t"
let svbool_t = Base "svbool_t"
let svint32_t = Base "svint32_t"
let pteval_t = Base "pteval_t"
let pte = Pointer pteval_t
let ins_t = Base "ins_t"

let rec  dump = function
  | Base s -> s
  | Volatile (Base s) -> "volatile " ^ s
  | Atomic (Base s) -> "_Atomic " ^ s
  | Volatile t -> sprintf "%s volatile" (dump t)
  | Const t -> sprintf "%s const" (dump t)
  | Atomic t -> sprintf "_Atomic (%s)" (dump t)
  | Pointer t -> dump t  ^ "*"
  | Array (t,sz) -> sprintf "%s_%i_t" t sz

let rec  debug = function
  | Base s -> sprintf "<%s>" s
  | Volatile (Base s) -> "volatile <" ^ s ^ ">"
  | Atomic (Base s) -> "_Atomic " ^ s
  | Volatile t -> sprintf "%s volatile" (debug t)
  | Const t -> sprintf "%s const" (debug t)
  | Atomic t -> sprintf "_Atomic (%s)" (debug t)
  | Pointer t -> debug t  ^ "*"
  | Array (t,sz) -> sprintf "%s[%i]" t sz

type fmt = Direct of string | Macro of string

let fmt10 = function
  | "atomic_t"
  | "int"|"char" ->  Some (Direct "d")
  | "ins_t" -> Some (Direct "s")
  | "long" -> Some (Direct "ld")
  | "int8_t" -> Some (Macro  "PRIi8")
  | "uint8_t" -> Some (Macro  "PRIu8")
  | "int16_t" -> Some (Macro  "PRIi16")
  | "uint16_t" -> Some (Macro  "PRIu16")
  | "int32_t" -> Some (Macro  "PRIi32")
  | "uint32_t" -> Some (Macro  "PRIu32")
  | "int64_t" -> Some (Macro  "PRIi64")
  | "uint64_t" -> Some (Macro  "PRIu64")
  | "int128_t" | "__int128" -> Some (Direct "lld")
  | "uint128_t" | "__uint128_t" -> Some (Direct "llu")
  | "intprt_t" -> Some (Macro "PRIiPTR")
  | "uintprt_t" -> Some (Macro "PRIuPTR")
  | _ -> None

let fmt16 = function
  | "atomic_t"
  | "int"|"char" ->  Some (Direct "x")
  | "long" ->  Some (Direct "lx")
  | "int8_t" -> Some (Macro  "PRIx8")
  | "uint8_t" -> Some (Macro  "PRIx8")
  | "int16_t" -> Some (Macro  "PRIx16")
  | "uint16_t" -> Some (Macro  "PRIx16")
  | "int32_t" -> Some (Macro  "PRIx32")
  | "uint32_t" -> Some (Macro  "PRIx32")
  | "int64_t" -> Some (Macro  "PRIx64")
  | "uint64_t" -> Some (Macro  "PRIx64")
  | "int128_t" | "__int128"
  | "uint128_t" | "__uint128_t"
       -> Some (Direct "llx")
  | "intprt_t" -> Some (Macro "PRIxPTR")
  | "uintprt_t" -> Some (Macro "PRIxPTR")
  | "ins_t" -> Some (Direct "s")
  | _ -> None

let get_fmt hexa = if hexa then fmt16 else fmt10

let rec is_ptr =  function
  | Pointer _ -> true
  | Atomic t | Volatile t | Const t -> is_ptr t
  | Array _ | Base _ -> false

let rec is_pte t = match t with
| Base "pteval_t" -> true
| Atomic t|Volatile t -> is_pte t
| _ -> false

let rec is_array = function
  | Array _ -> true
  | Atomic t | Volatile t | Const t -> is_array t
  | Base _ | Pointer _ -> false

let rec is_atomic = function
  | Volatile t | Const t -> is_atomic t
  | Atomic _ -> true
  | Array _ | Base _ | Pointer _ -> false

let rec is_ins_t = function
  | Base "ins_t" -> true
  | Atomic t | Volatile t | Const t -> is_ins_t t
  | Array _|Base _|Pointer _ -> false

let is_ins_ptr_t = function
  | Pointer p -> is_ins_t p
  | Atomic _ | Volatile _ | Const _ | Array _|Base _ -> false

let rec strip_atomic = function
  | Volatile t -> Volatile (strip_atomic t)
  | Atomic t -> strip_atomic t (* We handle the case where we have malformed types *)
  | Const t -> Const (strip_atomic t)
  | Pointer t -> Pointer (strip_atomic t)
  | Base s -> Base s
  | Array (s,t) -> Array (s,t)

let rec strip_volatile = function
  | Atomic t -> Atomic (strip_volatile t)
  | Pointer t -> Pointer (strip_volatile t)
  | Const t -> Const (strip_volatile t)
  | Volatile t -> strip_volatile t (* We handle the case where we have malformed types*)
  | Base s -> Base s
  | Array (s,t) -> Array (s,t)

let rec strip_const = function
  | Atomic t -> Atomic (strip_const t)
  | Pointer t -> Pointer (strip_const t)
  | Volatile t -> Volatile (strip_const t)
  | Const t -> strip_const t (* handles the case of malformed types *)
  | Array (t,s) -> Array (t,s)
  | Base s -> Base s

let strip_attributes t = strip_const (strip_atomic (strip_volatile t))

let rec is_ptr_to_atomic = function
  | Volatile t -> is_ptr_to_atomic t
  | Const t -> is_ptr_to_atomic t
  | Pointer t -> is_atomic t
  | Array _ | Base _ | Atomic _ -> false

let same_base t0 t1 = match t0,t1 with
| Base s0,Base s1 ->
    begin match s0,s1 with
    | ("int8_t","uint8_t")|("uint8_t","int8_t")
    | ("int16_t","uint16_t")|("uint16_t","int16_t")
    | ("int32_t","uint32_t")|("uint32_t","int32_t")
    | ("int64_t","uint64_t")|("uint64_t","int64_t")
    | ("int128_t", "uint128_t")|("uint128_t","int128_t")
    | ("__int128", "__uint128")|("__uint128","__int128")
      -> true
    | _,_ -> false
    end
| _,_ -> false

let type_for_align i = Array ("uint8_t",i)

let element_type = function
  | Array (b,_) -> Base b
  | t -> Warn.fatal "Array type expected, found %s" (dump t)

let rec signed = function
  | Atomic t|Volatile t| Const t -> signed t
  | Pointer _|Array _ -> false
  | Base
      ("atomic_t"|"int"|"char"|"long"|
      "int8_t"|"int16_t"|"int32_t"|"int64_t"|"int128_t"|"__int128") -> true
 | Base _ -> false

(* Best effort *)
let do_base_size =
  let open MachSize in
  function
  | "char"|"int8_t"|"uint8_t" -> Some Byte
  | "short"|"int16_t"|"uint16_t" -> Some Short
  | "int"|"int32_t"|"uint32_t" -> Some Word
  | "int64_t"|"uint64_t" -> Some Quad
  | "int128_t"|"uint128_t"|"__int128"|"__uint128" -> Some S128
  | _ -> None

let rec base_size t = match t with
| Atomic t|Volatile t| Const t -> base_size t
| Pointer _|Array _ -> None
| Base b -> do_base_size b

let (>>=) = Option.bind
let apply f x = Some (f x)

let rec sizeof = function
  | Array (b,sz) ->
     do_base_size b >>= apply MachSize.nbytes >>= apply (( * ) sz)
  | Atomic t|Volatile t| Const t ->  sizeof t
  | Base b ->
     do_base_size b >>= apply MachSize.nbytes
  | Pointer _ -> None

let larger t1 t2 =
  match sizeof t1,sizeof t2 with
  | Some n1,Some n2 ->
     if n1 > n2 then t1
     else if n2 > n1 then t2
     else begin
       match signed t1,signed t2 with
       | (true,false) -> t2
       | (false,true) -> t1
       | _,_ -> t2
     end
  | (None,_)|(_,None) -> t1