source:
src/Clight/acc-0.1.spaces.patch
@
2745
Last change on this file since 2745 was 416, checked in by , 10 years ago | |
---|---|
File size: 130.1 KB |
-
cparser/AddCasts.ml
diff --git a/cparser/AddCasts.ml b/cparser/AddCasts.ml index 9ec128d..5f5184c 100644
a b let widening_cast env tfrom tto = 39 39 r1 < r2 || (r1 = r2 && is_signed_ikind k1 = is_signed_ikind k2) 40 40 | TFloat(k1, _), TFloat(k2, _) -> 41 41 float_rank k1 <= float_rank k2 42 | TPtr( ty1, _), TPtr(ty2, _)-> is_void_type env ty242 | TPtr(sp1, ty1, _), TPtr(sp2, ty2, _) when sp1 = sp2 -> is_void_type env ty2 43 43 | _, _ -> false 44 44 end 45 45 … … let cast_not_needed env tfrom tto = 52 52 let cast env e tto = 53 53 if cast_not_needed env e.etyp tto 54 54 then e 55 else {edesc = ECast(tto, e); etyp = tto }55 else {edesc = ECast(tto, e); etyp = tto; espace = Any} 56 56 57 57 (* Note: this pass applies only to simplified expressions 58 58 because casts cannot be materialized in op= expressions... *) … … let rec add_expr env e = 73 73 EUnop(op, e1') 74 74 | Opreincr | Opredecr | Opostincr | Opostdecr -> 75 75 assert false (* not simplified *) 76 in { edesc = desc; etyp = e.etyp }76 in { edesc = desc; etyp = e.etyp; espace = e.espace } 77 77 | EBinop(op, e1, e2, ty) -> 78 78 let e1' = add_expr env e1 in 79 79 let e2' = add_expr env e2 in … … let rec add_expr env e = 97 97 | Oadd_assign|Osub_assign|Omul_assign|Odiv_assign|Omod_assign 98 98 | Oand_assign|Oor_assign|Oxor_assign|Oshl_assign|Oshr_assign -> 99 99 assert false (* not simplified *) 100 in { edesc = desc; etyp = e.etyp }100 in { edesc = desc; etyp = e.etyp; espace = e.espace } 101 101 | EConditional(e1, e2, e3) -> 102 102 { edesc = 103 103 EConditional(add_expr env e1, add_expr env e2, add_expr env e3); 104 etyp = e.etyp } 104 etyp = e.etyp; 105 espace = e.espace } 105 106 | ECast(ty, e1) -> 106 { edesc = ECast(ty, add_expr env e1); etyp = e.etyp }107 { edesc = ECast(ty, add_expr env e1); etyp = e.etyp; espace = e.espace } 107 108 | ECall(e1, el) -> 108 109 assert false (* not simplified *) 109 110 … … let add_arguments env ty_fun args = 132 133 let ty_args = 133 134 match unroll env ty_fun with 134 135 | TFun(res, args, vararg, a) -> args 135 | TPtr( ty, a) ->136 | TPtr(_, ty, a) -> 136 137 begin match unroll env ty with 137 138 | TFun(res, args, vararg, a) -> args 138 139 | _ -> assert false … … let add_arguments env ty_fun args = 146 147 147 148 let add_topexpr env loc e = 148 149 match e.edesc with 149 | EBinop(Oassign, lhs, {edesc = ECall(e1, el); etyp = ty }, _) ->150 | EBinop(Oassign, lhs, {edesc = ECall(e1, el); etyp = ty; espace = space}, _) -> 150 151 let ecall = 151 152 {edesc = ECall(add_expr env e1, add_arguments env e1.etyp el); 152 etyp = ty } in153 etyp = ty; espace = space} in 153 154 if cast_not_needed env ty lhs.etyp then 154 155 sassign loc (add_expr env lhs) ecall 155 156 else begin … … let add_topexpr env loc e = 162 163 | ECall(e1, el) -> 163 164 let ecall = 164 165 {edesc = ECall(add_expr env e1, add_arguments env e1.etyp el); 165 etyp = e.etyp } in166 etyp = e.etyp; espace = e.espace} in 166 167 {sdesc = Sdo ecall; sloc = loc} 167 168 | _ -> 168 169 assert false … … let rec add_init env tto = function 175 176 | Init_array il -> 176 177 let ty_elt = 177 178 match unroll env tto with 178 | TArray( ty, _, _) -> ty | _ -> assert false in179 | TArray(_,ty, _, _) -> ty | _ -> assert false in 179 180 Init_array (List.map (add_init env ty_elt) il) 180 181 | Init_struct(id, fil) -> 181 182 Init_struct (id, List.map -
cparser/Bitfields.ml
diff --git a/cparser/Bitfields.ml b/cparser/Bitfields.ml index dea1862..c7dc25f 100644
a b let insertion_mask bf = 118 118 (Int64.pred (Int64.shift_left 1L bf.bf_size)) 119 119 bf.bf_pos in 120 120 (* Give the mask an hexadecimal string representation, nicer to read *) 121 {edesc = EConst(CInt(m, IUInt, sprintf "0x%LXU" m)); etyp = TInt(IUInt, []) }121 {edesc = EConst(CInt(m, IUInt, sprintf "0x%LXU" m)); etyp = TInt(IUInt, []); espace = Code} (* XXX are consts always Code? *) 122 122 123 123 (* Extract the value of a bitfield *) 124 124 … … signed int bitfield_signed_extract(unsigned int x, int ofs, int sz) 140 140 let bitfield_extract bf carrier = 141 141 let e1 = 142 142 {edesc = EBinop(Oshl, carrier, left_shift_count bf, TInt(IUInt, [])); 143 etyp = carrier.etyp } in143 etyp = carrier.etyp; espace = Any} in 144 144 let ty = TInt((if bf.bf_signed then IInt else IUInt), []) in 145 145 let e2 = 146 {edesc = ECast(ty, e1); etyp = ty } in146 {edesc = ECast(ty, e1); etyp = ty; espace = Any} in 147 147 {edesc = EBinop(Oshr, e2, right_shift_count bf, e2.etyp); 148 etyp = e2.etyp }148 etyp = e2.etyp; espace = Any} 149 149 150 150 (* Assign a bitfield within a carrier *) 151 151 … … unsigned int bitfield_insert(unsigned int x, int ofs, int sz, unsigned int y) 161 161 162 162 let bitfield_assign bf carrier newval = 163 163 let msk = insertion_mask bf in 164 let notmsk = {edesc = EUnop(Onot, msk); etyp = msk.etyp } in164 let notmsk = {edesc = EUnop(Onot, msk); etyp = msk.etyp; espace = Any} in 165 165 let newval_shifted = 166 166 {edesc = EBinop(Oshl, newval, intconst (Int64.of_int bf.bf_pos) IUInt, 167 167 TInt(IUInt,[])); 168 etyp = TInt(IUInt,[])} in 168 etyp = TInt(IUInt,[]); 169 espace = Any} in 169 170 let newval_masked = 170 171 {edesc = EBinop(Oand, newval_shifted, msk, TInt(IUInt,[])); 171 etyp = TInt(IUInt,[])} 172 etyp = TInt(IUInt,[]); 173 espace = Any} 172 174 and oldval_masked = 173 175 {edesc = EBinop(Oand, carrier, notmsk, TInt(IUInt,[])); 174 etyp = TInt(IUInt,[]) } in176 etyp = TInt(IUInt,[]); espace = Any} in 175 177 {edesc = EBinop(Oor, oldval_masked, newval_masked, TInt(IUInt,[])); 176 etyp = TInt(IUInt,[]) }178 etyp = TInt(IUInt,[]); espace = Any} 177 179 178 180 (* Expressions *) 179 181 … … let transf_expr env e = 188 190 189 191 let is_bitfield_access_ptr ty fieldname = 190 192 match unroll env ty with 191 | TPtr( ty', _) -> is_bitfield_access ty' fieldname193 | TPtr(_, ty', _) -> is_bitfield_access ty' fieldname 192 194 | _ -> None in 193 195 194 196 let rec texp e = … … let transf_expr env e = 201 203 let e1' = texp e1 in 202 204 begin match is_bitfield_access e1.etyp fieldname with 203 205 | None -> 204 {edesc = EUnop(Odot fieldname, e1'); etyp = e.etyp }206 {edesc = EUnop(Odot fieldname, e1'); etyp = e.etyp; espace = e1'.espace} 205 207 | Some bf -> 206 208 bitfield_extract bf 207 209 {edesc = EUnop(Odot bf.bf_carrier, e1'); 208 etyp = bf.bf_carrier_typ} 210 etyp = bf.bf_carrier_typ; 211 espace = e1'.espace} 209 212 end 210 213 211 214 | EUnop(Oarrow fieldname, e1) -> 212 215 let e1' = texp e1 in 213 216 begin match is_bitfield_access_ptr e1.etyp fieldname with 214 217 | None -> 215 {edesc = EUnop(Oarrow fieldname, e1'); etyp = e.etyp }218 {edesc = EUnop(Oarrow fieldname, e1'); etyp = e.etyp; espace = Any} 216 219 | Some bf -> 217 220 bitfield_extract bf 218 221 {edesc = EUnop(Oarrow bf.bf_carrier, e1'); 219 etyp = bf.bf_carrier_typ }222 etyp = bf.bf_carrier_typ; espace = Any} 220 223 end 221 224 222 225 | EUnop(op, e1) -> 223 226 (* Note: simplified expr, so no ++/-- *) 224 {edesc = EUnop(op, texp e1); etyp = e.etyp }227 {edesc = EUnop(op, texp e1); etyp = e.etyp; espace = e.espace} 225 228 226 229 | EBinop(Oassign, e1, e2, ty) -> 227 230 begin match e1.edesc with … … let transf_expr env e = 231 234 | None -> 232 235 {edesc = EBinop(Oassign, 233 236 {edesc = EUnop(Odot fieldname, lhs); 234 etyp = e1.etyp },237 etyp = e1.etyp; espace = lhs.espace}, 235 238 rhs, ty); 236 etyp = e.etyp} 239 etyp = e.etyp; 240 espace = e.espace} 237 241 | Some bf -> 238 242 let carrier = 239 243 {edesc = EUnop(Odot bf.bf_carrier, lhs); 240 etyp = bf.bf_carrier_typ} in 244 etyp = bf.bf_carrier_typ; 245 espace = lhs.espace} in 241 246 {edesc = EBinop(Oassign, carrier, 242 247 bitfield_assign bf carrier rhs, 243 248 carrier.etyp); 244 etyp = carrier.etyp} 249 etyp = carrier.etyp; 250 espace = lhs.espace} 245 251 end 246 252 | EUnop(Oarrow fieldname, e11) -> 247 253 let lhs = texp e11 in let rhs = texp e2 in … … let transf_expr env e = 249 255 | None -> 250 256 {edesc = EBinop(Oassign, 251 257 {edesc = EUnop(Oarrow fieldname, lhs); 252 etyp = e1.etyp}, 258 etyp = e1.etyp; 259 espace = e1.espace}, 253 260 rhs, ty); 254 etyp = e.etyp} 261 etyp = e.etyp; 262 espace = e.espace} 255 263 | Some bf -> 256 264 let carrier = 257 265 {edesc = EUnop(Oarrow bf.bf_carrier, lhs); 258 etyp = bf.bf_carrier_typ} in 266 etyp = bf.bf_carrier_typ; 267 espace = Any} in 259 268 {edesc = EBinop(Oassign, carrier, 260 269 bitfield_assign bf carrier rhs, 261 270 carrier.etyp); 262 etyp = carrier.etyp} 271 etyp = carrier.etyp; 272 espace = Any} 263 273 end 264 274 | _ -> 265 {edesc = EBinop(Oassign, texp e1, texp e2, e1.etyp); etyp = e1.etyp }275 {edesc = EBinop(Oassign, texp e1, texp e2, e1.etyp); etyp = e1.etyp; espace = e1.espace} 266 276 end 267 277 268 278 | EBinop(op, e1, e2, ty) -> 269 279 (* Note: simplified expr assumed, so no assign-op *) 270 {edesc = EBinop(op, texp e1, texp e2, ty); etyp = e.etyp }280 {edesc = EBinop(op, texp e1, texp e2, ty); etyp = e.etyp; espace = e.espace} 271 281 | EConditional(e1, e2, e3) -> 272 {edesc = EConditional(texp e1, texp e2, texp e3); etyp = e.etyp }282 {edesc = EConditional(texp e1, texp e2, texp e3); etyp = e.etyp; espace = e.espace} 273 283 | ECast(ty, e1) -> 274 {edesc = ECast(ty, texp e1); etyp = e.etyp }284 {edesc = ECast(ty, texp e1); etyp = e.etyp; espace = e.espace} 275 285 | ECall(e1, el) -> 276 {edesc = ECall(texp e1, List.map texp el); etyp = e.etyp }286 {edesc = ECall(texp e1, List.map texp el); etyp = e.etyp; espace = e.espace} 277 287 278 288 in texp e 279 289 … … let bitfield_initializer bf i = 325 335 let m = Int64.pred (Int64.shift_left 1L bf.bf_size) in 326 336 let e_mask = 327 337 {edesc = EConst(CInt(m, IUInt, sprintf "0x%LXU" m)); 328 etyp = TInt(IUInt, [])} in 338 etyp = TInt(IUInt, []); 339 espace = Any} in 329 340 let e_and = 330 341 {edesc = EBinop(Oand, e, e_mask, TInt(IUInt,[])); 331 etyp = TInt(IUInt,[])} in 342 etyp = TInt(IUInt,[]); 343 espace = Any} in 332 344 {edesc = EBinop(Oshl, e_and, intconst (Int64.of_int bf.bf_pos) IInt, 333 345 TInt(IUInt, [])); 334 etyp = TInt(IUInt, [])} 346 etyp = TInt(IUInt, []); 347 espace = Any} 335 348 | _ -> assert false 336 349 337 350 let rec pack_bitfield_init id carrier fld_init_list = … … let rec or_expr_list = function 354 367 | [e] -> e 355 368 | e1 :: el -> 356 369 {edesc = EBinop(Oor, e1, or_expr_list el, TInt(IUInt,[])); 357 etyp = TInt(IUInt,[])} 370 etyp = TInt(IUInt,[]); 371 espace = Any} 358 372 359 373 let rec transf_struct_init id fld_init_list = 360 374 match fld_init_list with … … let rec transf_struct_init id fld_init_list = 367 381 ({fld_name = bf.bf_carrier; fld_typ = bf.bf_carrier_typ; 368 382 fld_bitfield = None}, 369 383 Init_single {edesc = ECast(bf.bf_carrier_typ, or_expr_list el); 370 etyp = bf.bf_carrier_typ}) 384 etyp = bf.bf_carrier_typ; 385 espace = Any}) 371 386 :: transf_struct_init id rem' 372 387 with Not_found -> 373 388 (fld, i) :: transf_struct_init id rem -
cparser/Builtins.ml
diff --git a/cparser/Builtins.ml b/cparser/Builtins.ml index 8eb1abf..aa243fd 100644
a b let add_function (s, (res, args, va)) = 37 37 TFun(res, 38 38 Some (List.map (fun ty -> (Env.fresh_ident "", ty)) args), 39 39 va, []) in 40 let (id, env') = Env.enter_ident !env s Storage_extern ty in40 let (id, env') = Env.enter_ident !env s Storage_extern ty Code in 41 41 env := env'; 42 42 idents := id :: !idents; 43 decls := {gdesc = Gdecl( Storage_extern, id, ty, None); gloc = no_loc} :: !decls43 decls := {gdesc = Gdecl(Code, (Storage_extern, id, ty, None)); gloc = no_loc} :: !decls 44 44 45 45 type t = { 46 46 typedefs: (string * C.typ) list; -
cparser/C.mli
diff --git a/cparser/C.mli b/cparser/C.mli index d477acd..90df378 100644
a b type binary_operator = 124 124 125 125 (** Types *) 126 126 127 type memory_space = 128 | Any 129 | Data 130 | IData 131 | PData 132 | XData 133 | Code 134 127 135 type typ = 128 136 | TVoid of attributes 129 137 | TInt of ikind * attributes 130 138 | TFloat of fkind * attributes 131 | TPtr of typ * attributes132 | TArray of typ * int64 option * attributes139 | TPtr of memory_space * typ * attributes 140 | TArray of memory_space * typ * int64 option * attributes 133 141 | TFun of typ * (ident * typ) list option * bool * attributes 134 142 | TNamed of ident * attributes 135 143 | TStruct of ident * attributes … … type typ = 137 145 138 146 (** Expressions *) 139 147 140 type exp = { edesc: exp_desc; etyp: typ }148 type exp = { edesc: exp_desc; etyp: typ; espace: memory_space } 141 149 142 150 and exp_desc = 143 151 | EConst of constant … … type globdecl = 220 228 { gdesc: globdecl_desc; gloc: location } 221 229 222 230 and globdecl_desc = 223 | Gdecl of decl(* variable declaration, function prototype *)231 | Gdecl of memory_space * decl (* variable declaration, function prototype *) 224 232 | Gfundef of fundef (* function definition *) 225 233 | Gcompositedecl of struct_or_union * ident (* struct/union declaration *) 226 234 | Gcompositedef of struct_or_union * ident * field list -
cparser/Ceval.ml
diff --git a/cparser/Ceval.ml b/cparser/Ceval.ml index 0e22852..acf84aa 100644
a b let cast env ty_to ty_from v = 99 99 if is_signed env ty_from 100 100 then F(normalize_float (Int64.to_float n) fk) 101 101 else F(normalize_float (int64_unsigned_to_float n) fk) 102 | TPtr( ty, _), I n ->102 | TPtr(_, ty, _), I n -> 103 103 I (normalize_int n ptr_t_ikind) 104 | TPtr( ty, _), F n ->104 | TPtr(_, ty, _), F n -> 105 105 if n = 0.0 then I 0L else raise Notconst 106 | TPtr( ty, _), (S _ | WS _) ->106 | TPtr(_, ty, _), (S _ | WS _) -> 107 107 v 108 108 | _, _ -> 109 109 raise Notconst … … let constant_expr env ty e = 270 270 match unroll env ty, cast env e.etyp ty (expr env e) with 271 271 | TInt(ik, _), I n -> Some(CInt(n, ik, "")) 272 272 | TFloat(fk, _), F n -> Some(CFloat(n, fk, "")) 273 | TPtr(_, _ ), I 0L -> Some(CInt(0L, IInt, ""))274 | TPtr(_, _ ), S s -> Some(CStr s)275 | TPtr(_, _ ), WS s -> Some(CWStr s)273 | TPtr(_, _, _), I 0L -> Some(CInt(0L, IInt, "")) 274 | TPtr(_, _, _), S s -> Some(CStr s) 275 | TPtr(_, _, _), WS s -> Some(CWStr s) 276 276 | _ -> None 277 277 with Notconst -> None -
cparser/Cleanup.ml
diff --git a/cparser/Cleanup.ml b/cparser/Cleanup.ml index be28989..9644654 100644
a b let needed id = 40 40 (* Iterate [addref] on all syntactic categories. *) 41 41 42 42 let rec add_typ = function 43 | TPtr( ty, _) -> add_typ ty44 | TArray( ty, _, _) -> add_typ ty43 | TPtr(_, ty, _) -> add_typ ty 44 | TArray(_, ty, _, _) -> add_typ ty 45 45 | TFun(res, None, _, _) -> add_typ res 46 46 | TFun(res, Some params, _, _) -> add_typ res; add_vars params 47 47 | TNamed(id, _) -> addref id … … let rec add_init_globdecls accu = function 120 120 | [] -> accu 121 121 | g :: rem -> 122 122 match g.gdesc with 123 | Gdecl declwhen visible_decl decl ->123 | Gdecl (_,decl) when visible_decl decl -> 124 124 add_decl decl; add_init_globdecls accu rem 125 125 | Gfundef({fd_storage = Storage_default} as f) -> 126 126 add_fundef f; add_init_globdecls accu rem … … let rec add_needed_globdecls accu = function 135 135 | [] -> accu 136 136 | g :: rem -> 137 137 match g.gdesc with 138 | Gdecl( (sto, id, ty, init) as decl) ->138 | Gdecl(_, ((sto, id, ty, init) as decl)) -> 139 139 if needed id 140 140 then (add_decl decl; add_needed_globdecls accu rem) 141 141 else add_needed_globdecls (g :: accu) rem … … let rec simpl_globdecls accu = function 174 174 | g :: rem -> 175 175 let need = 176 176 match g.gdesc with 177 | Gdecl( (sto, id, ty, init) as decl) -> visible_decl decl || needed id177 | Gdecl(_, ((sto, id, ty, init) as decl)) -> visible_decl decl || needed id 178 178 | Gfundef f -> f.fd_storage = Storage_default || needed f.fd_name 179 179 | Gcompositedecl(_, id) -> needed id 180 180 | Gcompositedef(_, id, flds) -> needed id -
cparser/Cprint.ml
diff --git a/cparser/Cprint.ml b/cparser/Cprint.ml index 7d8f2b3..70aba81 100644
a b let rec dcl pp ty n = 67 67 fprintf pp "%s%a%t" (name_of_ikind k) attributes a n 68 68 | TFloat(k, a) -> 69 69 fprintf pp "%s%a%t" (name_of_fkind k) attributes a n 70 | TPtr( t, a) ->70 | TPtr(_, t, a) -> (* XXX *) 71 71 let n' pp = 72 72 match t with 73 73 | TFun _ | TArray _ -> fprintf pp " (*%a%t)" attributes a n 74 74 | _ -> fprintf pp " *%a%t" attributes a n in 75 75 dcl pp t n' 76 | TArray( t, sz, a) ->76 | TArray(_, t, sz, a) -> (* XXX *) 77 77 let n' pp = 78 78 begin match a with 79 79 | [] -> n pp … … let rec exp_of_stmt s = 353 353 | Sdo e -> e 354 354 | Sseq(s1, s2) -> 355 355 {edesc = EBinop(Ocomma, exp_of_stmt s1, exp_of_stmt s2, TVoid []); 356 etyp = TVoid []} 356 etyp = TVoid []; 357 espace = Any} 357 358 | Sif(e, s1, s2) -> 358 359 {edesc = EConditional(e, exp_of_stmt s1, exp_of_stmt s2); 359 etyp = TVoid []} 360 etyp = TVoid []; 361 espace = Any} 360 362 | _ -> 361 363 raise Not_expr 362 364 … … let rec stmt pp s = 373 375 fprintf pp "@[<v 2>if (%a) {@ %a@;<0 -2>}@]" 374 376 exp (0, e) stmt_block s1 375 377 | Sif(e, {sdesc = Sskip}, s2) -> 376 let not_e = {edesc = EUnop(Olognot, e); etyp = TInt(IInt, []) } in378 let not_e = {edesc = EUnop(Olognot, e); etyp = TInt(IInt, []); espace = Any} in 377 379 fprintf pp "@[<v 2>if (%a) {@ %a@;<0 -2>}@]" 378 380 exp (0, not_e) stmt_block s2 379 381 | Sif(e, s1, s2) -> … … let field pp f = 455 457 let globdecl pp g = 456 458 location pp g.gloc; 457 459 match g.gdesc with 458 | Gdecl d ->460 | Gdecl (_, d) -> (* XXX *) 459 461 fprintf pp "%a@ @ " full_decl d 460 462 | Gfundef f -> 461 463 fundef pp f -
cparser/Cutil.ml
diff --git a/cparser/Cutil.ml b/cparser/Cutil.ml index 49b25a2..4a43d09 100644
a b let rec add_attributes_type attr t = 71 71 | TVoid a -> TVoid (add_attributes attr a) 72 72 | TInt(ik, a) -> TInt(ik, add_attributes attr a) 73 73 | TFloat(fk, a) -> TFloat(fk, add_attributes attr a) 74 | TPtr( ty, a) -> TPtr(ty, add_attributes attr a)75 | TArray( ty, sz, a) -> TArray(add_attributes_type attr ty, sz, a)74 | TPtr(sp, ty, a) -> TPtr(sp, ty, add_attributes attr a) 75 | TArray(sp, ty, sz, a) -> TArray(sp, add_attributes_type attr ty, sz, a) 76 76 | TFun(ty, params, vararg, a) -> TFun(ty, params, vararg, add_attributes attr 77 77 a) 78 78 | TNamed(s, a) -> TNamed(s, add_attributes attr a) … … let rec attributes_of_type env t = 95 95 | TVoid a -> a 96 96 | TInt(ik, a) -> a 97 97 | TFloat(fk, a) -> a 98 | TPtr( ty, a) -> a99 | TArray( ty, sz, a) -> a (* correct? *)98 | TPtr(_, ty, a) -> a 99 | TArray(_, ty, sz, a) -> a (* correct? *) 100 100 | TFun(ty, params, vararg, a) -> a 101 101 | TNamed(s, a) -> attributes_of_type env (unroll env t) 102 102 | TStruct(s, a) -> a … … let rec change_attributes_type env (f: attributes -> attributes) t = 110 110 | TVoid a -> TVoid (f a) 111 111 | TInt(ik, a) -> TInt(ik, f a) 112 112 | TFloat(fk, a) -> TFloat(fk, f a) 113 | TPtr( ty, a) -> TPtr(ty, f a)114 | TArray( ty, sz, a) ->115 TArray( change_attributes_type env f ty, sz, a)113 | TPtr(sp, ty, a) -> TPtr(sp, ty, f a) 114 | TArray(sp, ty, sz, a) -> 115 TArray(sp, change_attributes_type env f ty, sz, a) 116 116 | TFun(ty, params, vararg, a) -> TFun(ty, params, vararg, f a) 117 117 | TNamed(s, a) -> 118 118 let t1 = unroll env t in … … let combine_types ?(noattrs = false) env t1 t2 = 166 166 TInt(comp_base ik1 ik2, comp_attr a1 a2) 167 167 | TFloat(fk1, a1), TFloat(fk2, a2) -> 168 168 TFloat(comp_base fk1 fk2, comp_attr a1 a2) 169 | TPtr( ty1, a1), TPtr(ty2, a2)->170 TPtr( comp ty1 ty2, comp_attr a1 a2)171 | TArray( ty1, sz1, a1), TArray(ty2, sz2, a2)->172 TArray( comp ty1 ty2, comp_array_size sz1 sz2, comp_attr a1 a2)169 | TPtr(sp1, ty1, a1), TPtr(sp2, ty2, a2) when sp1 = sp2 -> 170 TPtr(sp1, comp ty1 ty2, comp_attr a1 a2) 171 | TArray(sp1, ty1, sz1, a1), TArray(sp2, ty2, sz2, a2) when sp1 = sp2 -> 172 TArray(sp1, comp ty1 ty2, comp_array_size sz1 sz2, comp_attr a1 a2) 173 173 | TFun(ty1, params1, vararg1, a1), TFun(ty2, params2, vararg2, a2) -> 174 174 let (params, vararg) = 175 175 match params1, params2 with … … let rec alignof env t = 244 244 | TVoid _ -> !config.alignof_void 245 245 | TInt(ik, _) -> Some(alignof_ikind ik) 246 246 | TFloat(fk, _) -> Some(alignof_fkind fk) 247 | TPtr(_, _ ) -> Some(!config.alignof_ptr)248 | TArray( ty, _, _) -> alignof env ty247 | TPtr(_, _, _) -> Some(!config.alignof_ptr) 248 | TArray(_, ty, _, _) -> alignof env ty 249 249 | TFun(_, _, _, _) -> !config.alignof_fun 250 250 | TNamed(_, _) -> alignof env (unroll env t) 251 251 | TStruct(name, _) -> … … let rec sizeof env t = 302 302 | TVoid _ -> !config.sizeof_void 303 303 | TInt(ik, _) -> Some(sizeof_ikind ik) 304 304 | TFloat(fk, _) -> Some(sizeof_fkind fk) 305 | TPtr(_, _ ) -> Some(!config.sizeof_ptr)306 | TArray( ty, None, _) -> None307 | TArray( ty, Some n, _) as t' ->305 | TPtr(_, _, _) -> Some(!config.sizeof_ptr) (* FIXME *) 306 | TArray(_, ty, None, _) -> None 307 | TArray(_, ty, Some n, _) as t' -> 308 308 begin match sizeof env ty with 309 309 | None -> None 310 310 | Some s -> … … let sizeof_union env members = 343 343 344 344 let sizeof_struct env members = 345 345 let rec sizeof_rec ofs = function 346 | [] | [ { fld_typ = TArray(_, None, _) } ] ->346 | [] | [ { fld_typ = TArray(_, _, None, _) } ] -> 347 347 (* C99: ty[] allowed as last field *) 348 348 begin match alignof_struct_union env members with 349 349 | None -> None (* should not happen? *) … … let float_rank = function 472 472 473 473 let pointer_decay env t = 474 474 match unroll env t with 475 | TArray( ty, _, _) -> TPtr(ty, [])476 | TFun _ as ty -> TPtr( ty, [])475 | TArray(sp, ty, _, _) -> TPtr(sp, ty, []) 476 | TFun _ as ty -> TPtr(Code, ty, []) 477 477 | t -> t 478 478 479 479 (* The usual unary conversions (H&S 6.3.3) *) … … let unary_conversion env t = 489 489 TInt(kind, attr) 490 490 end 491 491 (* Arrays and functions decay automatically to pointers *) 492 | TArray( ty, _, _) -> TPtr(ty, [])493 | TFun _ as ty -> TPtr( ty, [])492 | TArray(sp, ty, _, _) -> TPtr(sp, ty, []) 493 | TFun _ as ty -> TPtr(Code, ty, []) 494 494 (* Other types are not changed *) 495 495 | t -> t 496 496 … … let argument_conversion env t = 540 540 (* Arrays and functions degrade automatically to pointers *) 541 541 (* Other types are not changed *) 542 542 match unroll env t with 543 | TArray( ty, _, _) -> TPtr(ty, [])544 | TFun _ as ty -> TPtr( ty, [])543 | TArray(sp, ty, _, _) -> TPtr(sp, ty, []) 544 | TFun _ as ty -> TPtr(Code, ty, []) 545 545 | _ -> t (* preserve typedefs *) 546 546 547 547 (* Conversion on function arguments (old-style unprototyped, or vararg *) … … let enum_ikind = IInt 584 584 let type_of_constant = function 585 585 | CInt(_, ik, _) -> TInt(ik, []) 586 586 | CFloat(_, fk, _) -> TFloat(fk, []) 587 | CStr _ -> TPtr( TInt(IChar, []), []) (* XXX or array? const? *)588 | CWStr _ -> TPtr( TInt(wchar_ikind, []), []) (* XXX or array? const? *)587 | CStr _ -> TPtr(Code, TInt(IChar, []), []) (* XXX or array? const? *) 588 | CWStr _ -> TPtr(Code, TInt(wchar_ikind, []), []) (* XXX or array? const? *) 589 589 | CEnum(_, _) -> TInt(IInt, []) 590 590 591 591 (* Check that a C expression is a lvalue *) … … let is_literal_0 e = 612 612 613 613 (* Check that an assignment is allowed *) 614 614 615 let valid_pointer_conv from tto = 616 match from, tto with 617 | Any, _ 618 | _, Any -> true 619 | f, t -> f = t 620 615 621 let valid_assignment env from tto = 616 622 match pointer_decay env from.etyp, pointer_decay env tto with 617 623 | (TInt _ | TFloat _), (TInt _ | TFloat _) -> true 618 624 | TInt _, TPtr _ -> is_literal_0 from 619 | TPtr(ty, _), TPtr(ty', _) -> 620 incl_attributes (attributes_of_type env ty) (attributes_of_type env ty') 625 | TPtr(sp, ty, _), TPtr(sp', ty', _) -> 626 valid_pointer_conv sp sp' 627 && incl_attributes (attributes_of_type env ty) (attributes_of_type env ty') 621 628 && (is_void_type env ty || is_void_type env ty' 622 629 || compatible_types env 623 630 (erase_attributes_type env ty) … … let valid_cast env tfrom tto = 643 650 (* Construct an integer constant *) 644 651 645 652 let intconst v ik = 646 { edesc = EConst(CInt(v, ik, "")); etyp = TInt(ik, []) }653 { edesc = EConst(CInt(v, ik, "")); etyp = TInt(ik, []); espace = Code } 647 654 648 655 (* Construct a float constant *) 649 656 650 657 let floatconst v fk = 651 { edesc = EConst(CFloat(v, fk, "")); etyp = TFloat(fk, []) }658 { edesc = EConst(CFloat(v, fk, "")); etyp = TFloat(fk, []); espace = Code } 652 659 653 660 (* Construct the literal "0" with void * type *) 654 661 655 662 let nullconst = 656 { edesc = EConst(CInt(0L, ptr_t_ikind, "0")); etyp = TPtr( TVoid [], []) }663 { edesc = EConst(CInt(0L, ptr_t_ikind, "0")); etyp = TPtr(Any, TVoid [], []); espace = Code } (* XXX *) 657 664 658 665 (* Construct a sequence *) 659 666 … … let sseq loc s1 s2 = 667 674 (* Construct an assignment statement *) 668 675 669 676 let sassign loc lv rv = 670 { sdesc = Sdo {edesc = EBinop(Oassign, lv, rv, lv.etyp); etyp = lv.etyp };677 { sdesc = Sdo {edesc = EBinop(Oassign, lv, rv, lv.etyp); etyp = lv.etyp; espace = lv.espace}; 671 678 sloc = loc } 672 679 673 680 (* Empty location *) -
cparser/Elab.ml
diff --git a/cparser/Elab.ml b/cparser/Elab.ml index 7204508..1978b6b 100644
a b let rec elab_attributes loc = function 270 270 | None -> elab_attributes loc al 271 271 | Some a -> add_attributes [a] (elab_attributes loc al) 272 272 273 let elab_attribute_space = function 274 | ("data", []) -> Some Data 275 | ("idata", []) -> Some IData 276 | ("pdata", []) -> Some PData 277 | ("xdata", []) -> Some XData 278 | ("code", []) -> Some Code 279 | _ -> None 280 281 let rec elab_attributes_space loc attrs = 282 let rec aux = function 283 | [] -> None 284 | h::t -> (match elab_attribute_space h with 285 | None -> aux t 286 | Some v -> Some (v,t)) 287 in match aux attrs with 288 | None -> Any 289 | Some (space, rest) -> 290 (match aux rest with 291 | None -> () 292 | Some _ -> warning loc "Multiple memory spaces given"); 293 space 294 273 295 (* Auxiliary for typespec elaboration *) 274 296 275 297 let typespec_rank = function (* Don't change this *) … … let typespec_rank = function (* Don't change this *) 288 310 289 311 let typespec_order t1 t2 = compare (typespec_rank t1) (typespec_rank t2) 290 312 313 291 314 (* Elaboration of a type specifier. Returns 4-tuple: 292 315 (storage class, "inline" flag, elaborated type, new env) 293 316 Optional argument "only" is true if this is a standalone … … let rec elab_specifier ?(only = false) loc env specifier = 302 325 let sto = ref Storage_default 303 326 and inline = ref false 304 327 and attr = ref [] 305 and tyspecs = ref [] in 328 and tyspecs = ref [] 329 and space = ref Any in 306 330 307 331 let do_specifier = function 308 332 | SpecTypedef -> () … … let rec elab_specifier ?(only = false) loc env specifier = 314 338 | CV_RESTRICT -> ARestrict in 315 339 attr := add_attributes [a] !attr 316 340 | SpecAttr a -> 317 attr := add_attributes (elab_attributes loc [a]) !attr 341 attr := add_attributes (elab_attributes loc [a]) !attr; 342 (match elab_attribute_space a with 343 | None -> () 344 | Some sp -> 345 if !space <> Any then 346 error loc "multiple memory space specifiers"; 347 space := sp) 318 348 | SpecStorage st -> 319 349 if !sto <> Storage_default then 320 350 error loc "multiple storage specifiers"; … … let rec elab_specifier ?(only = false) loc env specifier = 330 360 331 361 List.iter do_specifier specifier; 332 362 333 let simple ty = (!s to, !inline, add_attributes_type !attr ty, env) in363 let simple ty = (!space, !sto, !inline, add_attributes_type !attr ty, env) in 334 364 335 365 (* Now interpret the list of type specifiers. Much of this code 336 366 is stolen from CIL. *) … … let rec elab_specifier ?(only = false) loc env specifier = 394 424 let (id', env') = 395 425 elab_struct_or_union only Struct loc id optmembers env in 396 426 let attr' = add_attributes !attr (elab_attributes loc a) in 397 (!s to, !inline, TStruct(id', attr'), env')427 (!space, !sto, !inline, TStruct(id', attr'), env') 398 428 399 429 | [Cabs.Tunion(id, optmembers, a)] -> 400 430 let (id', env') = 401 431 elab_struct_or_union only Union loc id optmembers env in 402 432 let attr' = add_attributes !attr (elab_attributes loc a) in 403 (!s to, !inline, TUnion(id', attr'), env')433 (!space, !sto, !inline, TUnion(id', attr'), env') 404 434 405 435 | [Cabs.Tenum(id, optmembers, a)] -> 406 436 let env' = 407 437 elab_enum loc id optmembers env in 408 438 let attr' = add_attributes !attr (elab_attributes loc a) in 409 (!s to, !inline, TInt(enum_ikind, attr'), env')439 (!space, !sto, !inline, TInt(enum_ikind, attr'), env') 410 440 411 441 | [Cabs.TtypeofE _] -> 412 442 fatal_error loc "GCC __typeof__ not supported" … … let rec elab_specifier ?(only = false) loc env specifier = 419 449 420 450 (* Elaboration of a type declarator. *) 421 451 422 and elab_type_declarator loc env ty = function452 and elab_type_declarator loc env space ty = function 423 453 | Cabs.JUSTBASE -> 424 ( ty, env)454 (space, ty, env) 425 455 | Cabs.PARENTYPE(attr1, d, attr2) -> 426 456 (* XXX ignoring the distinction between attrs after and before *) 427 457 let a = elab_attributes loc (attr1 @ attr2) in 428 elab_type_declarator loc env (add_attributes_type a ty) d 458 (* XXX ought to use space from attrs? *) 459 elab_type_declarator loc env space (add_attributes_type a ty) d 429 460 | Cabs.ARRAY(d, attr, sz) -> 430 461 let a = elab_attributes loc attr in 431 462 let sz' = … … and elab_type_declarator loc env ty = function 440 471 | None -> 441 472 error loc "array size is not a compile-time constant"; 442 473 Some 1L in (* produces better error messages later *) 443 elab_type_declarator loc env (TArray(ty, sz', a)) d474 elab_type_declarator loc env space (TArray(space, ty, sz', a)) d 444 475 | Cabs.PTR(attr, d) -> 445 476 let a = elab_attributes loc attr in 446 elab_type_declarator loc env (TPtr(ty, a)) d 477 let space' = elab_attributes_space loc attr in 478 elab_type_declarator loc env space' (TPtr(space, ty, a)) d 447 479 | Cabs.PROTO(d, params, vararg) -> 448 480 begin match unroll env ty with 449 481 | TArray _ | TFun _ -> … … and elab_type_declarator loc env ty = function 451 483 | _ -> () 452 484 end; 453 485 let params' = elab_parameters env params in 454 elab_type_declarator loc env (TFun(ty, params', vararg, [])) d486 elab_type_declarator loc env space (TFun(ty, params', vararg, [])) d 455 487 456 488 (* Elaboration of parameters in a prototype *) 457 489 … … and elab_parameter env (spec, name) = 476 508 "'extern' or 'static' storage not supported for function parameter"; 477 509 (* replace array and function types by pointer types *) 478 510 let ty1 = argument_conversion env1 ty in 479 let (id', env2) = Env.enter_ident env1 id sto ty1 in511 let (id', env2) = Env.enter_ident env1 id sto ty1 Any (* stack *) in 480 512 ( (id', ty1) , env2 ) 481 513 482 514 (* Elaboration of a (specifier, Cabs "name") pair *) 483 515 484 516 and elab_name env spec (id, decl, attr, loc) = 485 let (s to, inl, bty, env') = elab_specifier loc env spec in486 let ( ty, env'') = elab_type_declarator loc env'bty decl in517 let (space, sto, inl, bty, env') = elab_specifier loc env spec in 518 let (_, ty, env'') = elab_type_declarator loc env' space bty decl in 487 519 let a = elab_attributes loc attr in 488 520 (id, sto, inl, add_attributes_type a ty, env'') 489 521 490 522 (* Elaboration of a name group *) 491 523 492 524 and elab_name_group env (spec, namelist) = 493 let (s to, inl, bty, env') =525 let (space, sto, inl, bty, env') = 494 526 elab_specifier (loc_of_namelist namelist) env spec in 495 527 let elab_one_name env (id, decl, attr, loc) = 496 let ( ty, env1) =497 elab_type_declarator loc env bty decl in528 let (_, ty, env1) = 529 elab_type_declarator loc env space bty decl in 498 530 let a = elab_attributes loc attr in 499 531 ((id, sto, add_attributes_type a ty), env1) in 500 532 mmap elab_one_name env' namelist … … and elab_name_group env (spec, namelist) = 502 534 (* Elaboration of an init-name group *) 503 535 504 536 and elab_init_name_group env (spec, namelist) = 505 let (s to, inl, bty, env') =537 let (space, sto, inl, bty, env') = 506 538 elab_specifier (loc_of_init_name_list namelist) env spec in 507 539 let elab_one_name env ((id, decl, attr, loc), init) = 508 let ( ty, env1) =509 elab_type_declarator loc env bty decl in540 let (space', ty, env1) = 541 elab_type_declarator loc env space bty decl in 510 542 let a = elab_attributes loc attr in 511 (( id, sto, add_attributes_type a ty, init), env1) in543 ((space', id, sto, add_attributes_type a ty, init), env1) in 512 544 mmap elab_one_name env' namelist 513 545 514 546 (* Elaboration of a field group *) … … and elab_struct_or_union_info kind loc env members = 558 590 (* Check for incomplete types *) 559 591 let rec check_incomplete = function 560 592 | [] -> () 561 | [ { fld_typ = TArray( ty_elt, None, _) } ] when kind = Struct -> ()593 | [ { fld_typ = TArray(_, ty_elt, None, _) } ] when kind = Struct -> () 562 594 (* C99: ty[] allowed as last field of a struct *) 563 595 | fld :: rem -> 564 596 if incomplete_type env' fld.fld_typ then … … and elab_enum loc tag optmembers env = 663 695 (* Elaboration of a naked type, e.g. in a cast *) 664 696 665 697 let elab_type loc env spec decl = 666 let (s to, inl, bty, env') = elab_specifier loc env spec in667 let ( ty, env'') = elab_type_declarator loc env'bty decl in698 let (space, sto, inl, bty, env') = elab_specifier loc env spec in 699 let (_, ty, env'') = elab_type_declarator loc env' space bty decl in 668 700 if sto <> Storage_default || inl then 669 701 error loc "'extern', 'static', 'register' and 'inline' are meaningless in cast"; 670 702 ty 671 703 704 705 let join_spaces s1 s2 = 706 if s1 = s2 then s1 else Any 707 672 708 673 709 674 710 (* Elaboration of expressions *) -
cparser/Env.ml
@@ -687,15 +723,15 @@ let elab_expr loc env a = | VARIABLE s -> begin match wrap Env.lookup_ident loc env s with - | (id, II_ident(sto, ty)) -> - { edesc = EVar id; etyp = ty } + | (id, II_ident(sto, ty, spc)) -> + { edesc = EVar id; etyp = ty; espace=spc } | (id, II_enum v) -> - { edesc = EConst(CEnum(id, v)); etyp = TInt(enum_ikind, []) } + { edesc = EConst(CEnum(id, v)); etyp = TInt(enum_ikind, []); espace = Code } end | CONSTANT cst -> let cst' = elab_constant loc cst in - { edesc = EConst cst'; etyp = type_of_constant cst' } + { edesc = EConst cst'; etyp = type_of_constant cst'; espace = Code } | PAREN e -> elab e @@ -704,12 +740,12 @@ let elab_expr loc env a = | INDEX(a1, a2) -> (* e1[e2] *) let b1 = elab a1 in let b2 = elab a2 in - let tres = + let space, tres = match (unroll env b1.etyp, unroll env b2.etyp) with - | (TPtr(t, _) | TArray(t, _, _)), TInt _ -> t - | TInt _, (TPtr(t, _) | TArray(t, _, _)) -> t + | (TPtr(space, t, _) | TArray(space, t, _, _)), TInt _ -> space, t + | TInt _, (TPtr(space, t, _) | TArray(space, t, _, _)) -> space, t | t1, t2 -> error "incorrect types for array subscripting" in - { edesc = EBinop(Oindex, b1, b2, TPtr(tres, [])); etyp = tres } + { edesc = EBinop(Oindex, b1, b2, TPtr(space, tres, [])); etyp = tres; espace = space } | MEMBEROF(a1, fieldname) -> let b1 = elab a1 in @@ -723,25 +759,27 @@ let elab_expr loc env a = error "left-hand side of '.' is not a struct or union" in (* A field of a const/volatile struct or union is itself const/volatile *) { edesc = EUnop(Odot fieldname, b1); - etyp = add_attributes_type attrs fld.fld_typ } + etyp = add_attributes_type attrs fld.fld_typ; + espace = b1.espace } | MEMBEROFPTR(a1, fieldname) -> let b1 = elab a1 in - let (fld, attrs) = + let (space, fld, attrs) = match unroll env b1.etyp with - | TPtr(t, _) -> + | TPtr(space, t, _) -> begin match unroll env t with | TStruct(id, attrs) -> - (wrap Env.find_struct_member loc env (id, fieldname), attrs) + (space, wrap Env.find_struct_member loc env (id, fieldname), attrs) | TUnion(id, attrs) -> - (wrap Env.find_union_member loc env (id, fieldname), attrs) + (space, wrap Env.find_union_member loc env (id, fieldname), attrs) | _ -> error "left-hand side of '->' is not a pointer to a struct or union" end | _ -> error "left-hand side of '->' is not a pointer " in { edesc = EUnop(Oarrow fieldname, b1); - etyp = add_attributes_type attrs fld.fld_typ } + etyp = add_attributes_type attrs fld.fld_typ; + espace = space } (* Hack to treat vararg.h functions the GCC way. Helps with testing. va_start(ap,n) @@ -754,13 +792,15 @@ let elab_expr loc env a = | CALL((VARIABLE "__builtin_va_start" as a1), [a2; a3]) -> let b1 = elab a1 and b2 = elab a2 and b3 = elab a3 in { edesc = ECall(b1, [b2; {edesc = EUnop(Oaddrof, b3); - etyp = TPtr(b3.etyp, [])}]); - etyp = TVoid [] } + etyp = TPtr(b3.espace, b3.etyp, []); + espace = Any }]); + etyp = TVoid []; + espace = Any (* XXX ? *) } | CALL((VARIABLE "__builtin_va_arg" as a1), [a2; (TYPE_SIZEOF _) as a3]) -> let b1 = elab a1 and b2 = elab a2 and b3 = elab a3 in let ty = match b3.edesc with ESizeof ty -> ty | _ -> assert false in - { edesc = ECall(b1, [b2; b3]); etyp = ty } + { edesc = ECall(b1, [b2; b3]); etyp = ty; espace = Any (* XXX ? *) } | CALL(a1, al) -> let b1 = @@ -771,15 +811,15 @@ let elab_expr loc env a = let ty = TFun(TInt(IInt, []), None, false, []) in (* Emit an extern declaration for it *) let id = Env.fresh_ident n in - emit_elab (elab_loc loc) (Gdecl(Storage_extern, id, ty, None)); - { edesc = EVar id; etyp = ty } + emit_elab (elab_loc loc) (Gdecl(Code, (Storage_extern, id, ty, None))); + { edesc = EVar id; etyp = ty; espace = Any } | _ -> elab a1 in let bl = List.map elab al in (* Extract type information *) let (res, args, vararg) = match unroll env b1.etyp with | TFun(res, args, vararg, a) -> (res, args, vararg) - | TPtr(ty, a) -> + | TPtr(_, ty, a) -> begin match unroll env ty with | TFun(res, args, vararg, a) -> (res, args, vararg) | _ -> error "the function part of a call does not have a function type" @@ -791,7 +831,7 @@ let elab_expr loc env a = match args with | None -> bl | Some proto -> elab_arguments 1 bl proto vararg in - { edesc = ECall(b1, bl'); etyp = res } + { edesc = ECall(b1, bl'); etyp = res; espace = Any (* Stack *) } | UNARY(POSINCR, a1) -> elab_pre_post_incr_decr Opostincr "postfix '++'" a1 @@ -805,50 +845,50 @@ let elab_expr loc env a = let b1 = elab a1 in if not (valid_cast env b1.etyp ty) then err "illegal cast from %a@ to %a" Cprint.typ b1.etyp Cprint.typ ty; - { edesc = ECast(ty, b1); etyp = ty } + { edesc = ECast(ty, b1); etyp = ty; espace = b1.espace } | CAST ((spec, dcl), _) -> error "cast of initializer expression is not supported" | EXPR_SIZEOF(CONSTANT(CONST_STRING s)) -> let cst = CInt(Int64.of_int (String.length s), size_t_ikind, "") in - { edesc = EConst cst; etyp = type_of_constant cst } + { edesc = EConst cst; etyp = type_of_constant cst; espace = Code } | EXPR_SIZEOF a1 -> let b1 = elab a1 in if sizeof env b1.etyp = None then err "incomplete type %a" Cprint.typ b1.etyp; - { edesc = ESizeof b1.etyp; etyp = TInt(size_t_ikind, []) } + { edesc = ESizeof b1.etyp; etyp = TInt(size_t_ikind, []); espace = Code } | TYPE_SIZEOF (spec, dcl) -> let ty = elab_type loc env spec dcl in if sizeof env ty = None then err "incomplete type %a" Cprint.typ ty; - { edesc = ESizeof ty; etyp = TInt(size_t_ikind, []) } + { edesc = ESizeof ty; etyp = TInt(size_t_ikind, []); espace = Code } | UNARY(PLUS, a1) -> let b1 = elab a1 in if not (is_arith_type env b1.etyp) then error "argument of unary '+' is not an arithmetic type"; - { edesc = EUnop(Oplus, b1); etyp = unary_conversion env b1.etyp } + { edesc = EUnop(Oplus, b1); etyp = unary_conversion env b1.etyp; espace = Any } | UNARY(MINUS, a1) -> let b1 = elab a1 in if not (is_arith_type env b1.etyp) then error "argument of unary '-' is not an arithmetic type"; - { edesc = EUnop(Ominus, b1); etyp = unary_conversion env b1.etyp } + { edesc = EUnop(Ominus, b1); etyp = unary_conversion env b1.etyp; espace = Any } | UNARY(BNOT, a1) -> let b1 = elab a1 in if not (is_integer_type env b1.etyp) then error "argument of '~' is not an integer type"; - { edesc = EUnop(Onot, b1); etyp = unary_conversion env b1.etyp } + { edesc = EUnop(Onot, b1); etyp = unary_conversion env b1.etyp; espace = Any } | UNARY(NOT, a1) -> let b1 = elab a1 in if not (is_scalar_type env b1.etyp) then error "argument of '!' is not a scalar type"; - { edesc = EUnop(Olognot, b1); etyp = TInt(IInt, []) } + { edesc = EUnop(Olognot, b1); etyp = TInt(IInt, []); espace = Any } | UNARY(ADDROF, a1) -> let b1 = elab a1 in @@ -857,15 +897,15 @@ let elab_expr loc env a = | _ -> if not (is_lvalue env b1) then err "argument of '&' is not a l-value" end; - { edesc = EUnop(Oaddrof, b1); etyp = TPtr(b1.etyp, []) } + { edesc = EUnop(Oaddrof, b1); etyp = TPtr(b1.espace, b1.etyp, []); espace = Any } | UNARY(MEMOF, a1) -> let b1 = elab a1 in begin match unroll env b1.etyp with (* '*' applied to a function type has no effect *) | TFun _ -> b1 - | TPtr(ty, _) | TArray(ty, _, _) -> - { edesc = EUnop(Oderef, b1); etyp = ty } + | TPtr(space, ty, _) | TArray(space, ty, _, _) -> + { edesc = EUnop(Oderef, b1); etyp = ty; espace = space } | _ -> error "argument of unary '*' is not a pointer" end @@ -893,16 +933,16 @@ let elab_expr loc env a = if is_arith_type env b1.etyp && is_arith_type env b2.etyp then binary_conversion env b1.etyp b2.etyp else begin - let (ty, attr) = + let (space, ty, attr) = match unroll env b1.etyp, unroll env b2.etyp with - | (TPtr(ty, a) | TArray(ty, _, a)), TInt _ -> (ty, a) - | TInt _, (TPtr(ty, a) | TArray(ty, _, a)) -> (ty, a) + | (TPtr(space, ty, a) | TArray(space, ty, _, a)), TInt _ -> (space, ty, a) + | TInt _, (TPtr(space, ty, a) | TArray(space, ty, _, a)) -> (space, ty, a) | _, _ -> error "type error in binary '+'" in if not (pointer_arithmetic_ok env ty) then err "illegal pointer arithmetic in binary '+'"; - TPtr(ty, attr) + TPtr(space, ty, attr) end in - { edesc = EBinop(Oadd, b1, b2, tyres); etyp = tyres } + { edesc = EBinop(Oadd, b1, b2, tyres); etyp = tyres; espace = Any } | BINARY(SUB, a1, a2) -> let b1 = elab a1 in @@ -913,24 +953,25 @@ let elab_expr loc env a = (tyres, tyres) end else begin match unroll env b1.etyp, unroll env b2.etyp with - | (TPtr(ty, a) | TArray(ty, _, a)), TInt _ -> + | (TPtr(space, ty, a) | TArray(space, ty, _, a)), TInt _ -> if not (pointer_arithmetic_ok env ty) then err "illegal pointer arithmetic in binary '-'"; - (TPtr(ty, a), TPtr(ty, a)) - | TInt _, (TPtr(ty, a) | TArray(ty, _, a)) -> + (TPtr(space, ty, a), TPtr(space, ty, a)) + | TInt _, (TPtr(space, ty, a) | TArray(space, ty, _, a)) -> if not (pointer_arithmetic_ok env ty) then err "illegal pointer arithmetic in binary '-'"; - (TPtr(ty, a), TPtr(ty, a)) - | (TPtr(ty1, a1) | TArray(ty1, _, a1)), - (TPtr(ty2, a2) | TArray(ty2, _, a2)) -> - if not (compatible_types ~noattrs:true env ty1 ty2) then + (TPtr(space, ty, a), TPtr(space, ty, a)) + | (TPtr(space1, ty1, a1) | TArray(space1, ty1, _, a1)), + (TPtr(space2, ty2, a2) | TArray(space2, ty2, _, a2)) -> +(* TODO: automatic cast on space mismatch? *) + if not (compatible_types ~noattrs:true env ty1 ty2) || space1 != space2 then err "mismatch between pointer types in binary '-'"; if not (pointer_arithmetic_ok env ty1) then err "illegal pointer arithmetic in binary '-'"; - (TPtr(ty1, []), TInt(ptrdiff_t_ikind, [])) + (TPtr(space1, ty1, []), TInt(ptrdiff_t_ikind, [])) | _, _ -> error "type error in binary '-'" end in - { edesc = EBinop(Osub, b1, b2, tyop); etyp = tyres } + { edesc = EBinop(Osub, b1, b2, tyop); etyp = tyres; espace = Any } | BINARY(SHL, a1, a2) -> elab_shift "<<" Oshl a1 a2 @@ -970,35 +1011,38 @@ let elab_expr loc env a = let b1 = elab a1 in let b2 = elab a2 in let b3 = elab a3 in + let space = join_spaces b2.espace b3.espace in if not (is_scalar_type env b1.etyp) then err ("the first argument of '? :' is not a scalar type"); begin match pointer_decay env b2.etyp, pointer_decay env b3.etyp with | (TInt _ | TFloat _), (TInt _ | TFloat _) -> { edesc = EConditional(b1, b2, b3); - etyp = binary_conversion env b2.etyp b3.etyp } - | TPtr(ty1, a1), TPtr(ty2, a2) -> + etyp = binary_conversion env b2.etyp b3.etyp; + espace = space } + (* TODO: maybe we should automatically cast to a generic pointer when the spaces don't match? *) + | TPtr(sp1, ty1, a1), TPtr(sp2, ty2, a2) -> let tyres = - if is_void_type env ty1 || is_void_type env ty2 then - TPtr(TVoid [], add_attributes a1 a2) + if (is_void_type env ty1 || is_void_type env ty2) && sp1 = sp2 then + TPtr(sp1, TVoid [], add_attributes a1 a2) else match combine_types ~noattrs:true env - (TPtr(ty1, a1)) (TPtr(ty2, a2)) with + (TPtr(sp1, ty1, a1)) (TPtr(sp2, ty2, a2)) with | None -> error "the second and third arguments of '? :' \ have incompatible pointer types" | Some ty -> ty in - { edesc = EConditional(b1, b2, b3); etyp = tyres } - | TPtr(ty1, a1), TInt _ when is_literal_0 b3 -> - { edesc = EConditional(b1, b2, nullconst); etyp = TPtr(ty1, a1) } - | TInt _, TPtr(ty2, a2) when is_literal_0 b2 -> - { edesc = EConditional(b1, nullconst, b3); etyp = TPtr(ty2, a2) } + { edesc = EConditional(b1, b2, b3); etyp = tyres; espace = space } + | TPtr(sp1, ty1, a1), TInt _ when is_literal_0 b3 -> + { edesc = EConditional(b1, b2, nullconst); etyp = TPtr(sp1, ty1, a1); espace = space } + | TInt _, TPtr(sp2, ty2, a2) when is_literal_0 b2 -> + { edesc = EConditional(b1, nullconst, b3); etyp = TPtr(sp2, ty2, a2); espace = space } | ty1, ty2 -> match combine_types env ty1 ty2 with | None -> error ("the second and third arguments of '? :' have incompatible types") | Some tyres -> - { edesc = EConditional(b1, b2, b3); etyp = tyres } + { edesc = EConditional(b1, b2, b3); etyp = tyres; espace = space } end (* 7.9 Assignment expressions *) @@ -1018,7 +1062,7 @@ let elab_expr loc env a = err "assigning a value of type@ %a@ to a lvalue of type@ %a" Cprint.typ b2.etyp Cprint.typ b1.etyp; end; - { edesc = EBinop(Oassign, b1, b2, b1.etyp); etyp = b1.etyp } + { edesc = EBinop(Oassign, b1, b2, b1.etyp); etyp = b1.etyp; espace = b1.espace } | BINARY((ADD_ASSIGN | SUB_ASSIGN | MUL_ASSIGN | DIV_ASSIGN | MOD_ASSIGN | BAND_ASSIGN | BOR_ASSIGN | XOR_ASSIGN | SHL_ASSIGN | SHR_ASSIGN @@ -1050,7 +1094,7 @@ let elab_expr loc env a = err "assigning a value of type@ %a@ to a lvalue of type@ %a" Cprint.typ ty Cprint.typ b1.etyp; end; - { edesc = EBinop(top, b1, b2, ty); etyp = b1.etyp } + { edesc = EBinop(top, b1, b2, ty); etyp = b1.etyp; espace = b1.espace } | _ -> assert false end @@ -1063,7 +1107,7 @@ let elab_expr loc env a = | [] -> accu | a :: l -> let b = elab a in - elab_comma { edesc = EBinop(Ocomma, accu, b, b.etyp); etyp = b.etyp } l + elab_comma { edesc = EBinop(Ocomma, accu, b, b.etyp); etyp = b.etyp; espace = b.espace } l in elab_comma (elab a1) al (* Extensions that we do not handle *) @@ -1099,7 +1143,7 @@ let elab_expr loc env a = err "the argument of %s is not a l-value" msg; if not (is_scalar_type env b1.etyp) then err "the argument of %s must be an arithmetic or pointer type" msg; - { edesc = EUnop(op, b1); etyp = b1.etyp } + { edesc = EUnop(op, b1); etyp = b1.etyp; espace = b1.espace } (* Elaboration of binary operators over integers *) and elab_binary_integer msg op a1 a2 = @@ -1110,7 +1154,7 @@ let elab_expr loc env a = if not (is_integer_type env b2.etyp) then error "the second argument of '%s' is not an integer type" msg; let tyres = binary_conversion env b1.etyp b2.etyp in - { edesc = EBinop(op, b1, b2, tyres); etyp = tyres } + { edesc = EBinop(op, b1, b2, tyres); etyp = tyres; espace = Any } (* Elaboration of binary operators over arithmetic types *) and elab_binary_arithmetic msg op a1 a2 = @@ -1121,7 +1165,7 @@ let elab_expr loc env a = if not (is_arith_type env b2.etyp) then error "the second argument of '%s' is not an arithmetic type" msg; let tyres = binary_conversion env b1.etyp b2.etyp in - { edesc = EBinop(op, b1, b2, tyres); etyp = tyres } + { edesc = EBinop(op, b1, b2, tyres); etyp = tyres; espace = Any } (* Elaboration of shift operators *) and elab_shift msg op a1 a2 = @@ -1132,7 +1176,7 @@ let elab_expr loc env a = if not (is_integer_type env b2.etyp) then error "the second argument of '%s' is not an integer type" msg; let tyres = unary_conversion env b1.etyp in - { edesc = EBinop(op, b1, b2, tyres); etyp = tyres } + { edesc = EBinop(op, b1, b2, tyres); etyp = tyres; espace = Any } (* Elaboration of comparisons *) and elab_comparison op a1 a2 = @@ -1142,28 +1186,28 @@ let elab_expr loc env a = match pointer_decay env b1.etyp, pointer_decay env b2.etyp with | (TInt _ | TFloat _), (TInt _ | TFloat _) -> EBinop(op, b1, b2, binary_conversion env b1.etyp b2.etyp) - | TInt _, TPtr(ty, _) when is_literal_0 b1 -> - EBinop(op, nullconst, b2, TPtr(ty, [])) - | TPtr(ty, _), TInt _ when is_literal_0 b2 -> - EBinop(op, b1, nullconst, TPtr(ty, [])) - | TPtr(ty1, _), TPtr(ty2, _) + | TInt _, TPtr(sp, ty, _) when is_literal_0 b1 -> + EBinop(op, nullconst, b2, TPtr(sp, ty, [])) + | TPtr(sp, ty, _), TInt _ when is_literal_0 b2 -> + EBinop(op, b1, nullconst, TPtr(sp, ty, [])) + | TPtr(sp1, ty1, _), TPtr(sp2, ty2, _) when is_void_type env ty1 -> - EBinop(op, b1, b2, TPtr(ty2, [])) - | TPtr(ty1, _), TPtr(ty2, _) + EBinop(op, b1, b2, TPtr(sp2, ty2, [])) (* XXX sp1? *) + | TPtr(sp1, ty1, _), TPtr(sp2, ty2, _) when is_void_type env ty2 -> - EBinop(op, b1, b2, TPtr(ty1, [])) - | TPtr(ty1, _), TPtr(ty2, _) -> + EBinop(op, b1, b2, TPtr(sp1, ty1, [])) (* XXX sp2? *) + | TPtr(sp1, ty1, _), TPtr(sp2, ty2, _) -> if not (compatible_types ~noattrs:true env ty1 ty2) then warning "comparison between incompatible pointer types"; - EBinop(op, b1, b2, TPtr(ty1, [])) - | TPtr _, TInt _ - | TInt _, TPtr _ -> + EBinop(op, b1, b2, TPtr(sp1, ty1, [])) (* XXX sp1? *) + | TPtr (sp,_,_), TInt _ + | TInt _, TPtr (sp,_,_) -> warning "comparison between integer and pointer"; - EBinop(op, b1, b2, TPtr(TVoid [], [])) + EBinop(op, b1, b2, TPtr(sp,TVoid [], [])) | ty1, ty2 -> error "illegal comparison between types@ %a@ and %a" Cprint.typ b1.etyp Cprint.typ b2.etyp in - { edesc = resdesc; etyp = TInt(IInt, []) } + { edesc = resdesc; etyp = TInt(IInt, []); espace = Any } (* Elaboration of && and || *) and elab_logical_operator msg op a1 a2 = @@ -1173,7 +1217,7 @@ let elab_expr loc env a = let b2 = elab a2 in if not (is_scalar_type env b2.etyp) then err "the second argument of '%s' is not a scalar type" msg; - { edesc = EBinop(op, b1, b2, TInt(IInt, [])); etyp = TInt(IInt, []) } + { edesc = EBinop(op, b1, b2, TInt(IInt, [])); etyp = TInt(IInt, []); espace = Any } (* Type-checking of function arguments *) and elab_arguments argno args params vararg = @@ -1271,7 +1315,7 @@ let check_init_type loc env a ty = let rec elab_init loc env ty ile = match unroll env ty with - | TArray(ty_elt, opt_sz, _) -> + | TArray(space, ty_elt, opt_sz, _) -> let rec elab_init_array n accu rem = match opt_sz, rem with | Some sz, _ when n >= sz -> @@ -1390,8 +1434,8 @@ let elab_initial loc env ty ie = let fixup_typ env ty init = match unroll env ty, init with - | TArray(ty_elt, None, attr), Init_array il -> - TArray(ty_elt, Some(Int64.of_int(List.length il)), attr) + | TArray(space, ty_elt, None, attr), Init_array il -> + TArray(space, ty_elt, Some(Int64.of_int(List.length il)), attr) | _ -> ty (* Entry point *) @@ -1416,9 +1460,9 @@ let enter_typedef loc env (s, sto, ty) = emit_elab (elab_loc loc) (Gtypedef(id, ty)); env' -let enter_or_refine_ident local loc env s sto ty = +let enter_or_refine_ident local loc env s sto ty space = match redef Env.lookup_ident env s with - | Some(id, II_ident(old_sto, old_ty)) -> + | Some(id, II_ident(old_sto, old_ty, old_space)) -> let new_ty = if local then begin error loc "redefinition of local variable '%s'" s; @@ -1437,17 +1481,18 @@ let enter_or_refine_ident local loc env s sto ty = warning loc "redefinition of '%s' with incompatible storage class" s; sto end in - (id, Env.add_ident env id new_sto new_ty) + let new_space = join_spaces old_space space (* XXX: incompatible? *) in + (id, Env.add_ident env id new_sto new_ty new_space) | Some(id, II_enum v) -> error loc "illegal redefinition of enumerator '%s'" s; - (id, Env.add_ident env id sto ty) + (id, Env.add_ident env id sto ty space) | _ -> - Env.enter_ident env s sto ty + Env.enter_ident env s sto ty space let rec enter_decdefs local loc env = function | [] -> ([], env) - | (s, sto, ty, init) :: rem -> + | (space, s, sto, ty, init) :: rem -> (* Sanity checks on storage class *) begin match sto with | Storage_extern -> @@ -1462,11 +1507,11 @@ let rec enter_decdefs local loc env = function match unroll env ty with TFun _ -> Storage_extern | _ -> sto in (* enter ident in environment with declared type, because initializer can refer to the ident *) - let (id, env1) = enter_or_refine_ident local loc env s sto' ty in + let (id, env1) = enter_or_refine_ident local loc env s sto' ty space in (* process the initializer *) let (ty', init') = elab_initializer loc env1 ty init in (* update environment with refined type *) - let env2 = Env.add_ident env1 id sto' ty' in + let env2 = Env.add_ident env1 id sto' ty' space in (* check for incomplete type *) if sto' <> Storage_extern && incomplete_type env ty' then warning loc "'%s' has incomplete type" s; @@ -1476,7 +1521,7 @@ let rec enter_decdefs local loc env = function ((sto', id, ty', init') :: decls, env3) end else begin (* Global definition *) - emit_elab (elab_loc loc) (Gdecl(sto, id, ty', init')); + emit_elab (elab_loc loc) (Gdecl(space, (sto, id, ty', init'))); enter_decdefs local loc env2 rem end @@ -1496,10 +1541,10 @@ let elab_fundef env (spec, name) body loc1 loc2 = | TFun(ty_ret, Some params, vararg, attr) -> (ty_ret, params, vararg) | _ -> fatal_error loc1 "wrong type for function definition" in (* Enter function in the environment, for recursive references *) - let (fun_id, env1) = enter_or_refine_ident false loc1 env s sto ty in + let (fun_id, env1) = enter_or_refine_ident false loc1 env s sto ty Code in (* Enter parameters in the environment *) let env2 = - List.fold_left (fun e (id, ty) -> Env.add_ident e id Storage_default ty) + List.fold_left (fun e (id, ty) -> Env.add_ident e id Storage_default ty Any) (Env.new_scope env1) params in (* Elaborate function body *) let body' = !elab_block_f loc2 ty_ret env2 body in @@ -1538,7 +1583,7 @@ let rec elab_definition (local: bool) (env: Env.t) (def: Cabs.definition) (* "struct s { ...};" or "union u;" *) | ONLYTYPEDEF(spec, loc) -> - let (sto, inl, ty, env') = elab_specifier ~only:true loc env spec in + let (space, sto, inl, ty, env') = elab_specifier ~only:true loc env spec in if sto <> Storage_default || inl then error loc "Non-default storage or 'inline' on 'struct' or 'union' declaration"; ([], env') diff --git a/cparser/Env.ml b/cparser/Env.ml index 777b3e1..1f41c0c 100644
a b type composite_info = { 70 70 (* Infos associated with an ordinary identifier *) 71 71 72 72 type ident_info = 73 | II_ident of storage * typ 73 | II_ident of storage * typ * memory_space 74 74 | II_enum of int64 (* value of the enum *) 75 75 76 76 (* Infos associated with a typedef *) … … let find_typedef env id = 201 201 202 202 (* Inserting things by source name, with generation of a translated name *) 203 203 204 let enter_ident env s sto ty =204 let enter_ident env s sto ty sp = 205 205 let id = fresh_ident s in 206 206 (id, 207 { env with env_ident = IdentMap.add id (II_ident(sto, ty )) env.env_ident })207 { env with env_ident = IdentMap.add id (II_ident(sto, ty, sp)) env.env_ident }) 208 208 209 209 let enter_composite env s ci = 210 210 let id = fresh_ident s in … … let enter_typedef env s info = 220 220 221 221 (* Inserting things by translated name *) 222 222 223 let add_ident env id sto ty =224 { env with env_ident = IdentMap.add id (II_ident(sto, ty )) env.env_ident }223 let add_ident env id sto ty sp = 224 { env with env_ident = IdentMap.add id (II_ident(sto, ty, sp)) env.env_ident } 225 225 226 226 let add_composite env id ci = 227 227 { env with env_tag = IdentMap.add id ci env.env_tag } -
cparser/Env.mli
diff --git a/cparser/Env.mli b/cparser/Env.mli index e7a74af..a9daa21 100644
a b type composite_info = { 31 31 ci_sizeof: int option; (* size; None if incomplete *) 32 32 } 33 33 34 type ident_info = II_ident of C.storage * C.typ | II_enum of int6434 type ident_info = II_ident of C.storage * C.typ * C.memory_space | II_enum of int64 35 35 36 36 type typedef_info = C.typ 37 37 … … val find_struct_member : t -> C.ident * string -> C.field 60 60 val find_union_member : t -> C.ident * string -> C.field 61 61 val find_typedef : t -> C.ident -> typedef_info 62 62 63 val enter_ident : t -> string -> C.storage -> C.typ -> C. ident * t63 val enter_ident : t -> string -> C.storage -> C.typ -> C.memory_space -> C.ident * t 64 64 val enter_composite : t -> string -> composite_info -> C.ident * t 65 65 val enter_enum_item : t -> string -> int64 -> C.ident * t 66 66 val enter_typedef : t -> string -> typedef_info -> C.ident * t 67 67 68 val add_ident : t -> C.ident -> C.storage -> C.typ -> t68 val add_ident : t -> C.ident -> C.storage -> C.typ -> C.memory_space -> t 69 69 val add_composite : t -> C.ident -> composite_info -> t 70 70 val add_typedef : t -> C.ident -> typedef_info -> t -
cparser/GCC.ml
diff --git a/cparser/GCC.ml b/cparser/GCC.ml index 9f864dc..17f3cfa 100644
a b let ulongLongType = TInt(IULongLong, []) 30 30 let floatType = TFloat(FFloat, []) 31 31 let doubleType = TFloat(FDouble, []) 32 32 let longDoubleType = TFloat (FLongDouble, []) 33 let voidPtrType = TPtr( TVoid [], [])34 let voidConstPtrType = TPtr( TVoid [AConst], [])35 let charPtrType = TPtr( TInt(IChar, []), [])36 let charConstPtrType = TPtr( TInt(IChar, [AConst]), [])37 let intPtrType = TPtr( TInt(IInt, []), [])33 let voidPtrType = TPtr(Any,TVoid [], []) 34 let voidConstPtrType = TPtr(Any,TVoid [AConst], []) 35 let charPtrType = TPtr(Any,TInt(IChar, []), []) 36 let charConstPtrType = TPtr(Any,TInt(IChar, [AConst]), []) 37 let intPtrType = TPtr(Any,TInt(IInt, []), []) 38 38 let sizeType = TInt(size_t_ikind, []) 39 39 40 40 let builtins = { … … let builtins = { 150 150 "__builtin_log10l", (longDoubleType, [ longDoubleType ], false); 151 151 152 152 "__builtin_modff", (floatType, [ floatType; 153 TPtr( floatType,[]) ], false);153 TPtr(Any,floatType,[]) ], false); 154 154 "__builtin_modfl", (longDoubleType, [ longDoubleType; 155 TPtr( longDoubleType, []) ],155 TPtr(Any,longDoubleType, []) ], 156 156 false); 157 157 158 158 "__builtin_nan", (doubleType, [ charConstPtrType ], false); -
cparser/Lexer.mll
diff --git a/cparser/Lexer.mll b/cparser/Lexer.mll index d4947ad..d3f3958 100644
a b let init_lexicon _ = 181 181 ("__builtin_types_compatible_p", fun loc -> BUILTIN_TYPES_COMPAT loc); 182 182 ("__builtin_offsetof", fun loc -> BUILTIN_OFFSETOF loc); 183 183 (* On some versions of GCC __thread is a regular identifier *) 184 ("__thread", fun loc -> THREAD loc) 184 ("__thread", fun loc -> THREAD loc); 185 (* 8051 memory space extensions *) 186 ("__data", fun loc -> DATA loc); 187 ("__idata", fun loc -> IDATA loc); 188 ("__pdata", fun loc -> PDATA loc); 189 ("__xdata", fun loc -> XDATA loc); 190 ("__code", fun loc -> CODE loc); 185 191 ] 186 192 187 193 (* Mark an identifier as a type name. The old mapping is preserved and will -
cparser/Parser.mly
diff --git a/cparser/Parser.mly b/cparser/Parser.mly index 0eebb84..abec574 100644
a b let transformOffsetOf (speclist, dtype) member = 221 221 %token<Cabs.cabsloc> VOLATILE EXTERN STATIC CONST RESTRICT AUTO REGISTER 222 222 %token<Cabs.cabsloc> THREAD 223 223 224 %token<Cabs.cabsloc> DATA IDATA PDATA XDATA CODE 225 224 226 %token<Cabs.cabsloc> SIZEOF ALIGNOF 225 227 226 228 %token EQ PLUS_EQ MINUS_EQ STAR_EQ SLASH_EQ PERCENT_EQ … … attribute_nocv: 1249 1251 | MSATTR { (fst $1, []), snd $1 } 1250 1252 /* ISO 6.7.3 */ 1251 1253 | THREAD { ("__thread",[]), $1 } 1254 1255 | DATA { ("data",[]), $1 } 1256 | IDATA { ("idata",[]), $1 } 1257 | PDATA { ("pdata",[]), $1 } 1258 | XDATA { ("xdata",[]), $1 } 1259 | CODE { ("code",[]), $1 } 1252 1260 ; 1253 1261 1254 1262 attribute_nocv_list: -
cparser/Rename.ml
diff --git a/cparser/Rename.ml b/cparser/Rename.ml index 4b2f350..b6de8cd 100644
a b let ident env id = 75 75 id.name id.stamp 76 76 77 77 let rec typ env = function 78 | TPtr( ty, a) -> TPtr(typ env ty, a)79 | TArray( ty, sz, a) -> TArray(typ env ty, sz, a)78 | TPtr(sp, ty, a) -> TPtr(sp, typ env ty, a) 79 | TArray(sp, ty, sz, a) -> TArray(sp, typ env ty, sz, a) 80 80 | TFun(res, None, va, a) -> TFun(typ env res, None, va, a) 81 81 | TFun(res, Some p, va, a) -> 82 82 let (p', _) = mmap param env p in … … let constant env = function 97 97 | cst -> cst 98 98 99 99 let rec exp env e = 100 { edesc = exp_desc env e.edesc; etyp = typ env e.etyp }100 { edesc = exp_desc env e.edesc; etyp = typ env e.etyp; espace = e.espace } 101 101 102 102 and exp_desc env = function 103 103 | EConst cst -> EConst(constant env cst) … … let rec globdecl env g = 191 191 ( { gdesc = desc'; gloc = g.gloc }, env' ) 192 192 193 193 and globdecl_desc env = function 194 | Gdecl d->194 | Gdecl (sp,d) -> 195 195 let (d', env') = decl env d in 196 (Gdecl d', env')196 (Gdecl (sp,d'), env') 197 197 | Gfundef fd -> 198 198 let (fd', env') = fundef env fd in 199 199 (Gfundef fd', env') … … let rec reserve_public env = function 230 230 | dcl :: rem -> 231 231 let env' = 232 232 match dcl.gdesc with 233 | Gdecl (sto, id, _, _) ->233 | Gdecl (_, (sto, id, _, _)) -> 234 234 begin match sto with 235 235 | Storage_default | Storage_extern -> enter_global env id 236 236 | Storage_static -> env -
cparser/SimplExpr.ml
diff --git a/cparser/SimplExpr.ml b/cparser/SimplExpr.ml index 330b184..8202cb2 100644
a b let simpl_expr loc env e act = 92 92 93 93 let eboolvalof e = 94 94 { edesc = EBinop(One, e, intconst 0L IInt, TInt(IInt, [])); 95 etyp = TInt(IInt, []) } in 95 etyp = TInt(IInt, []); 96 espace = Any } in 96 97 97 98 let sseq s1 s2 = Cutil.sseq loc s1 s2 in 98 99 99 100 let sassign e1 e2 = 100 { sdesc = Sdo {edesc = EBinop(Oassign, e1, e2, e1.etyp); etyp = e1.etyp };101 { sdesc = Sdo {edesc = EBinop(Oassign, e1, e2, e1.etyp); etyp = e1.etyp; espace = e1.espace}; 101 102 sloc = loc } in 102 103 103 104 let sif e s1 s2 = … … let simpl_expr loc env e act = 149 150 150 151 | Ominus | Oplus | Olognot | Onot | Oderef | Oarrow _ -> 151 152 let (s1, e1') = simpl e1 RHS in 152 finish act s1 {edesc = EUnop(op, e1'); etyp = e.etyp }153 finish act s1 {edesc = EUnop(op, e1'); etyp = e.etyp; espace = e.espace} 153 154 154 155 | Oaddrof -> 155 156 let (s1, e1') = simpl e1 LHS in 156 finish act s1 {edesc = EUnop(op, e1'); etyp = e.etyp }157 finish act s1 {edesc = EUnop(op, e1'); etyp = e.etyp; espace = e.espace} 157 158 158 159 | Odot _ -> 159 160 let (s1, e1') = simpl e1 (if act = LHS then LHS else RHS) in 160 finish act s1 {edesc = EUnop(op, e1'); etyp = e.etyp }161 finish act s1 {edesc = EUnop(op, e1'); etyp = e.etyp; espace = e.espace} 161 162 162 163 | Opreincr | Opredecr -> 163 164 let (s1, e1') = simpl e1 LHS in … … let simpl_expr loc env e act = 165 166 let op' = match op with Opreincr -> Oadd | _ -> Osub in 166 167 let ty = unary_conversion env e.etyp in 167 168 let e3 = 168 {edesc = EBinop(op', e2', intconst 1L IInt, ty); etyp = ty } in169 {edesc = EBinop(op', e2', intconst 1L IInt, ty); etyp = ty; espace = Any} in 169 170 begin match act with 170 171 | Drop -> 171 172 (sseq s1 (sseq s2 (sassign e1' e3)), voidconst) … … let simpl_expr loc env e act = 184 185 | Drop -> 185 186 let (s2, e2') = lhs_to_rhs e1' in 186 187 let e3 = 187 {edesc = EBinop(op', e2', intconst 1L IInt, ty); etyp = ty } in188 {edesc = EBinop(op', e2', intconst 1L IInt, ty); etyp = ty; espace = Any} in 188 189 (sseq s1 (sseq s2 (sassign e1' e3)), voidconst) 189 190 | _ -> 190 191 let tmp = new_temp e.etyp in 191 192 let e3 = 192 {edesc = EBinop(op', tmp, intconst 1L IInt, ty); etyp = ty } in193 {edesc = EBinop(op', tmp, intconst 1L IInt, ty); etyp = ty; espace = Any} in 193 194 finish act (sseq s1 (sseq (sassign tmp e1') (sassign e1' e3))) 194 195 tmp 195 196 end … … let simpl_expr loc env e act = 205 206 let (s1, e1') = simpl e1 RHS in 206 207 let (s2, e2') = simpl e2 RHS in 207 208 finish act (sseq s1 s2) 208 {edesc = EBinop(op, e1', e2', ty); etyp = e.etyp }209 {edesc = EBinop(op, e1', e2', ty); etyp = e.etyp; espace = Any} 209 210 210 211 | Oassign -> 211 212 if act = Drop && is_simpl_expr e1 then … … let simpl_expr loc env e act = 239 240 | Oshl_assign -> Oshl | Oshr_assign -> Oshr 240 241 | _ -> assert false in 241 242 let e3 = 242 { edesc = EBinop(op', e11', e2', ty); etyp = ty } in243 { edesc = EBinop(op', e11', e2', ty); etyp = ty; espace = Any } in 243 244 begin match act with 244 245 | Drop -> 245 246 (sseq s1 (sseq s11 (sseq s2 (sassign e1' e3))), voidconst) … … let simpl_expr loc env e act = 259 260 let (s1, e1') = simpl e1 RHS in 260 261 if is_simpl_expr e2 then begin 261 262 finish act s1 262 {edesc = EBinop(Ologand, e1', e2, ty); etyp = e.etyp }263 {edesc = EBinop(Ologand, e1', e2, ty); etyp = e.etyp; espace = e.espace} 263 264 end else begin 264 265 match act with 265 266 | Drop -> … … let simpl_expr loc env e act = 284 285 let (s1, e1') = simpl e1 RHS in 285 286 if is_simpl_expr e2 then begin 286 287 finish act s1 287 {edesc = EBinop(Ologor, e1', e2, ty); etyp = e.etyp }288 {edesc = EBinop(Ologor, e1', e2, ty); etyp = e.etyp; espace = e.espace} 288 289 end else begin 289 290 match act with 290 291 | Drop -> … … let simpl_expr loc env e act = 310 311 | EConditional(e1, e2, e3) -> 311 312 let (s1, e1') = simpl e1 RHS in 312 313 if is_simpl_expr e2 && is_simpl_expr e3 then begin 313 finish act s1 {edesc = EConditional(e1', e2, e3); etyp = e.etyp }314 finish act s1 {edesc = EConditional(e1', e2, e3); etyp = e.etyp; espace = e.espace} 314 315 end else begin 315 316 match act with 316 317 | Drop -> … … let simpl_expr loc env e act = 336 337 simpl e1 act 337 338 end else begin 338 339 let (s1, e1') = simpl e1 RHS in 339 finish act s1 {edesc = ECast(ty, e1'); etyp = e.etyp }340 finish act s1 {edesc = ECast(ty, e1'); etyp = e.etyp; espace = e.espace} 340 341 end 341 342 342 343 | ECall(e1, el) -> 343 344 let (s1, e1') = simpl e1 RHS in 344 345 let (s2, el') = simpl_list el in 345 let e2 = { edesc = ECall(e1', el'); etyp = e.etyp } in346 let e2 = { edesc = ECall(e1', el'); etyp = e.etyp; espace = e.espace } in 346 347 begin match act with 347 348 | Drop -> 348 349 (sseq s1 (sseq s2 {sdesc = Sdo e2; sloc=loc}), voidconst) … … let simpl_statement env s = 481 482 let (s', _) = simpl_expr s.sloc env e (Set tmp) in 482 483 let s_init = 483 484 {sdesc = Sdo {edesc = EBinop(Oassign, tmp, intconst 1L IInt, tmp.etyp); 484 etyp = tmp.etyp };485 etyp = tmp.etyp; espace = tmp.espace}; 485 486 sloc = s.sloc} in 486 487 {sdesc = Sfor(s_init, tmp, s', simpl_stmt s1); sloc = s.sloc} 487 488 end -
cparser/StructAssign.ml
diff --git a/cparser/StructAssign.ml b/cparser/StructAssign.ml index f5cecfc..5af7bed 100644
a b let maxsize = ref 8 28 28 let need_memcpy = ref (None: ident option) 29 29 30 30 let memcpy_type = 31 TFun(TPtr( TVoid [], []),32 Some [(Env.fresh_ident "", TPtr( TVoid [], []));33 (Env.fresh_ident "", TPtr( TVoid [AConst], []));31 TFun(TPtr(Any,TVoid [], []), 32 Some [(Env.fresh_ident "", TPtr(Any,TVoid [], [])); 33 (Env.fresh_ident "", TPtr(Any,TVoid [AConst], [])); 34 34 (Env.fresh_ident "", TInt(size_t_ikind, []))], 35 35 false, []) 36 36 … … let memcpy_ident () = 43 43 | Some id -> 44 44 id 45 45 46 let space_of_ty = function 47 | TArray(space, _, _, _) 48 | TPtr(space, _, _) -> space 49 | _ -> Any 50 46 51 let transf_assign env loc lhs rhs = 47 52 48 53 let num_assign = ref 0 in … … let transf_assign env loc lhs rhs = 62 67 transf_struct l r ci.ci_members 63 68 | TUnion(id, attr) -> 64 69 raise Exit 65 | TArray( ty_elt, Some sz, attr) ->66 transf_array lr ty_elt 0L sz67 | TArray( ty_elt, None, attr) ->70 | TArray(space, ty_elt, Some sz, attr) -> 71 transf_array space l (space_of_ty (unroll env r.etyp)) r ty_elt 0L sz 72 | TArray(space, ty_elt, None, attr) -> 68 73 error "%a: Error: array of unknown size" formatloc loc; 69 74 sskip (* will be ignored later *) 70 75 | _ -> … … let transf_assign env loc lhs rhs = 73 78 and transf_struct l r = function 74 79 | [] -> sskip 75 80 | f :: fl -> 76 sseq loc (transf {edesc = EUnop(Odot f.fld_name, l); etyp = f.fld_typ }77 {edesc = EUnop(Odot f.fld_name, r); etyp = f.fld_typ })81 sseq loc (transf {edesc = EUnop(Odot f.fld_name, l); etyp = f.fld_typ; espace = l.espace} 82 {edesc = EUnop(Odot f.fld_name, r); etyp = f.fld_typ; espace = r.espace}) 78 83 (transf_struct l r fl) 79 84 80 and transf_array l r ty idx sz =85 and transf_array lsp l rsp r ty idx sz = 81 86 if idx >= sz then sskip else begin 82 87 let e = intconst idx size_t_ikind in 83 sseq loc (transf {edesc = EBinop(Oindex, l, e, ty); etyp = ty }84 {edesc = EBinop(Oindex, r, e, ty); etyp = ty })85 (transf_array l r ty (Int64.add idx 1L) sz)88 sseq loc (transf {edesc = EBinop(Oindex, l, e, ty); etyp = ty; espace = lsp} 89 {edesc = EBinop(Oindex, r, e, ty); etyp = ty; espace = rsp}) 90 (transf_array lsp l rsp r ty (Int64.add idx 1L) sz) 86 91 end 87 92 in 88 93 89 94 try 90 95 transf lhs rhs 91 96 with Exit -> 92 let memcpy = {edesc = EVar(memcpy_ident()); etyp = memcpy_type} in 93 let e_lhs = {edesc = EUnop(Oaddrof, lhs); etyp = TPtr(lhs.etyp, [])} in 94 let e_rhs = {edesc = EUnop(Oaddrof, rhs); etyp = TPtr(rhs.etyp, [])} in 95 let e_size = {edesc = ESizeof(lhs.etyp); etyp = TInt(size_t_ikind, [])} in 97 let memcpy = {edesc = EVar(memcpy_ident()); etyp = memcpy_type; espace = Any} in 98 (* XXX: casts required? *) 99 let e_lhs = {edesc = EUnop(Oaddrof, lhs); etyp = TPtr(Any, lhs.etyp, []); espace = Any} in 100 let e_rhs = {edesc = EUnop(Oaddrof, rhs); etyp = TPtr(Any, rhs.etyp, []); espace = Any} in 101 let e_size = {edesc = ESizeof(lhs.etyp); etyp = TInt(size_t_ikind, []); espace = Any} in 96 102 {sdesc = Sdo {edesc = ECall(memcpy, [e_lhs; e_rhs; e_size]); 97 etyp = TVoid[] };103 etyp = TVoid[]; espace = Any}; 98 104 sloc = loc} 99 105 100 106 let rec transf_stmt env s = … … let program p = 136 142 match !need_memcpy with 137 143 | None -> p' 138 144 | Some id -> 139 {gdesc = Gdecl( Storage_extern, id, memcpy_type, None); gloc = no_loc}145 {gdesc = Gdecl(Code, (Storage_extern, id, memcpy_type, None)); gloc = no_loc} 140 146 :: p' 141 147 142 148 (* Horrible hack *) -
cparser/StructByValue.ml
diff --git a/cparser/StructByValue.ml b/cparser/StructByValue.ml index de79737..60e088b 100644
a b let rec transf_type env t = 38 38 let tres' = transf_type env tres in 39 39 if is_composite_type env tres then begin 40 40 let res = Env.fresh_ident "_res" in 41 TFun(TVoid [], Some((res, TPtr( tres', [])) :: args'), vararg, attr)41 TFun(TVoid [], Some((res, TPtr(Any, tres', [])) :: args'), vararg, attr) 42 42 end else 43 43 TFun(tres', Some args', vararg, attr) 44 | TPtr( t1, attr) ->44 | TPtr(sp, t1, attr) -> 45 45 let t1' = transf_type env t1 in 46 if t1' = t1 then t else TPtr( transf_type env t1, attr)47 | TArray( t1, sz, attr) ->46 if t1' = t1 then t else TPtr(sp, transf_type env t1, attr) 47 | TArray(sp, t1, sz, attr) -> 48 48 let t1' = transf_type env t1 in 49 if t1' = t1 then t else TArray( transf_type env t1, sz, attr)49 if t1' = t1 then t else TArray(sp, transf_type env t1, sz, attr) 50 50 | _ -> t 51 51 52 52 and transf_funarg env (id, t) = 53 53 let t = transf_type env t in 54 54 if is_composite_type env t 55 then (id, TPtr( add_attributes_type [AConst] t, []))55 then (id, TPtr(Any, add_attributes_type [AConst] t, [])) 56 56 else (id, t) 57 57 58 58 (* Simple exprs: no change in structure, since calls cannot occur within, … … and transf_funarg env (id, t) = 60 60 61 61 let rec transf_expr env e = 62 62 { etyp = transf_type env e.etyp; 63 espace = e.espace; 63 64 edesc = match e.edesc with 64 65 | EConst c -> EConst c 65 66 | ESizeof ty -> ESizeof (transf_type env ty) … … and transf_expr e = transf_expr env e in 104 105 let transf_arg e = 105 106 let e' = transf_expr e in 106 107 if is_composite_type env e'.etyp 107 then {edesc = EUnop(Oaddrof, e'); etyp = TPtr( e'.etyp, [])}108 then {edesc = EUnop(Oaddrof, e'); etyp = TPtr(Any, e'.etyp, []); espace = Any} (* XXX: this might require a cast? *) 108 109 else e' 109 110 in 110 111 … … in 118 119 let rec transf_stmt s = 119 120 match s.sdesc with 120 121 | Sskip -> s 121 | Sdo {edesc = ECall(fn, args); etyp = ty } ->122 | Sdo {edesc = ECall(fn, args); etyp = ty; espace = space} -> 122 123 let fn = transf_expr fn in 123 124 let args = List.map transf_arg args in 124 125 if is_composite_type env ty then begin 125 126 let tmp = new_temp ~name:"_res" ty in 126 let arg0 = {edesc = EUnop(Oaddrof, tmp); etyp = TPtr( ty, [])} in127 {s with sdesc = Sdo {edesc = ECall(fn, arg0 :: args); etyp = TVoid [] }}127 let arg0 = {edesc = EUnop(Oaddrof, tmp); etyp = TPtr(Any, ty, []); espace = Any} in 128 {s with sdesc = Sdo {edesc = ECall(fn, arg0 :: args); etyp = TVoid []; espace = Any}} 128 129 end else 129 {s with sdesc = Sdo {edesc = ECall(fn, args); etyp = ty }}130 | Sdo {edesc = EBinop(Oassign, dst, {edesc = ECall(fn, args); etyp = ty }, _)} ->130 {s with sdesc = Sdo {edesc = ECall(fn, args); etyp = ty; espace = space}} 131 | Sdo {edesc = EBinop(Oassign, dst, {edesc = ECall(fn, args); etyp = ty; espace = space}, _)} -> 131 132 let dst = transf_expr dst in 132 133 let fn = transf_expr fn in 133 134 let args = List.map transf_arg args in 134 135 let ty = transf_type ty in 135 136 if is_composite_type env ty then begin 136 let arg0 = {edesc = EUnop(Oaddrof, dst); etyp = TPtr( dst.etyp, [])} in137 {s with sdesc = Sdo {edesc = ECall(fn, arg0 :: args); etyp = TVoid [] }}137 let arg0 = {edesc = EUnop(Oaddrof, dst); etyp = TPtr(Any, dst.etyp, []); espace = Any} in 138 {s with sdesc = Sdo {edesc = ECall(fn, arg0 :: args); etyp = TVoid []; espace = Any}} 138 139 end else 139 sassign s.sloc dst {edesc = ECall(fn, args); etyp = ty }140 sassign s.sloc dst {edesc = ECall(fn, args); etyp = ty; espace = space} 140 141 | Sdo e -> 141 142 {s with sdesc = Sdo(transf_expr e)} 142 143 | Sseq(s1, s2) -> … … let transf_params loc env params = 184 185 let ty = transf_type env ty in 185 186 if is_composite_type env ty then begin 186 187 let id' = Env.fresh_ident id.name in 187 let ty' = TPtr( add_attributes_type [AConst] ty, []) in188 let ty' = TPtr(Any, add_attributes_type [AConst] ty, []) in 188 189 let (params', decls, init) = transf_prm params in 189 190 ((id', ty') :: params', 190 191 (Storage_default, id, ty, None) :: decls, 191 192 sseq loc 192 (sassign loc {edesc = EVar id; etyp = ty} 193 {edesc = EUnop(Oderef, {edesc = EVar id'; etyp = ty'}); 194 etyp = ty}) 193 (sassign loc {edesc = EVar id; etyp = ty; espace = Any} 194 {edesc = EUnop(Oderef, {edesc = EVar id'; etyp = ty'; espace = Any}); 195 etyp = ty; 196 espace = Any}) 195 197 init) 196 198 end else begin 197 199 let (params', decls, init) = transf_prm params in … … let transf_fundef env f = 206 208 let (ret1, params1, body1) = 207 209 if is_composite_type env ret then begin 208 210 let vres = Env.fresh_ident "_res" in 209 let tres = TPtr( ret, []) in210 let eres = {edesc = EVar vres; etyp = tres } in211 let eeres = {edesc = EUnop(Oderef, eres); etyp = ret } in211 let tres = TPtr(Any, ret, []) in 212 let eres = {edesc = EVar vres; etyp = tres; espace = Any} in 213 let eeres = {edesc = EUnop(Oderef, eres); etyp = ret; espace = Any} in 212 214 (TVoid [], 213 215 (vres, tres) :: params, 214 216 transf_funbody env f.fd_body (Some eeres)) -
cparser/Transform.ml
diff --git a/cparser/Transform.ml b/cparser/Transform.ml index b7f57f3..1a9dd20 100644
a b let new_temp_var ?(name = "t") ty = 33 33 34 34 let new_temp ?(name = "t") ty = 35 35 let id = new_temp_var ~name ty in 36 { edesc = EVar id; etyp = ty }36 { edesc = EVar id; etyp = ty; espace = Any (* Always stack allocated? *) } 37 37 38 38 let get_temps () = 39 39 let temps = !temporaries in … … let program 58 58 | g :: gl -> 59 59 let (desc', env') = 60 60 match g.gdesc with 61 | Gdecl ((sto, id, ty, init) as d) ->62 (Gdecl( decl env d), Env.add_ident env id sto ty)61 | Gdecl (sp, ((sto, id, ty, init) as d)) -> 62 (Gdecl(sp, decl env d), Env.add_ident env id sto ty sp) 63 63 | Gfundef f -> 64 64 (Gfundef(fundef env f), 65 Env.add_ident env f.fd_name f.fd_storage (fundef_typ f) )65 Env.add_ident env f.fd_name f.fd_storage (fundef_typ f) Code) 66 66 | Gcompositedecl(su, id) -> 67 67 (Gcompositedecl(su, id), 68 68 Env.add_composite env id (composite_info_decl env su)) -
cparser/Unblock.ml
diff --git a/cparser/Unblock.ml b/cparser/Unblock.ml index fa304b7..d19940a 100644
a b let rec local_initializer loc env path init k = 32 32 match init with 33 33 | Init_single e -> 34 34 sdoseq loc 35 { edesc = EBinop(Oassign, path, e, path.etyp); etyp = path.etyp }35 { edesc = EBinop(Oassign, path, e, path.etyp); etyp = path.etyp; espace = path.espace } 36 36 k 37 37 | Init_array il -> 38 let ty_elt =38 let space, ty_elt = 39 39 match unroll env path.etyp with 40 | TArray( ty_elt, _, _) ->ty_elt40 | TArray(space, ty_elt, _, _) -> space, ty_elt 41 41 | _ -> fatal_error "%aWrong type for array initializer" 42 42 formatloc loc in 43 43 let rec array_init pos = function 44 44 | [] -> k 45 45 | i :: il -> 46 46 local_initializer loc env 47 { edesc = EBinop(Oindex, path, intconst pos IInt, TPtr(ty_elt, [])); 48 etyp = ty_elt } 47 { edesc = EBinop(Oindex, path, intconst pos IInt, TPtr(space, ty_elt, [])); 48 etyp = ty_elt; 49 espace = Any } 49 50 i 50 51 (array_init (Int64.succ pos) il) in 51 52 array_init 0L il 52 53 | Init_struct(id, fil) -> 53 54 let field_init (fld, i) k = 54 55 local_initializer loc env 55 { edesc = EUnop(Odot fld.fld_name, path); etyp = fld.fld_typ }56 { edesc = EUnop(Odot fld.fld_name, path); etyp = fld.fld_typ; espace = Any } 56 57 i k in 57 58 List.fold_right field_init fil k 58 59 | Init_union(id, fld, i) -> 59 60 local_initializer loc env 60 { edesc = EUnop(Odot fld.fld_name, path); etyp = fld.fld_typ }61 { edesc = EUnop(Odot fld.fld_name, path); etyp = fld.fld_typ; espace = Any } 61 62 i k 62 63 63 64 (* Record new variables to be locally defined *) … … let process_decl loc env (sto, id, ty, optinit) k = 82 83 match optinit with 83 84 | None -> k 84 85 | Some init -> 85 local_initializer loc env { edesc = EVar id; etyp = ty' } init k86 local_initializer loc env { edesc = EVar id; etyp = ty'; espace = Any } init k 86 87 87 88 (* Simplification of blocks within a statement *) 88 89 -
src/acc.ml
diff --git a/src/acc.ml b/src/acc.ml index c8f6592..e2f782c 100644
a b let process filename = 33 33 src_language tgt_language input_ast 34 34 in 35 35 let final_ast, intermediate_asts = Misc.ListExt.cut_last target_asts in 36 let annotated_input_ast = Languages.annotate input_ast final_ast in 37 Languages.save filename annotated_input_ast; 36 if Options.annotation_requested () then begin 37 let annotated_input_ast = Languages.annotate input_ast final_ast in 38 Languages.save filename annotated_input_ast 39 end; 38 40 Languages.save filename final_ast; 39 41 if Options.is_debug_enabled () then 40 42 List.iter (Languages.save filename) intermediate_asts; 43 if Options.is_matita_output_enabled () then 44 Languages.save_matita filename (input_ast :: target_asts); 41 45 if Options.interpretation_requested () || Options.is_debug_enabled () then begin 42 46 let asts = input_ast :: target_asts in 43 47 let label_traces = List.map Languages.interpret asts in -
src/clight/clight.mli
diff --git a/src/clight/clight.mli b/src/clight/clight.mli index 4c9d638..b831ef0 100644
a b open AST 7 7 8 8 (** ** Types *) 9 9 10 type memory_space = Any | Data | IData | PData | XData | Code 11 10 12 (** Clight types are similar to those of C. They include numeric types, 11 13 pointers, arrays, function types, and composite types (struct and 12 14 union). Numeric types (integers and floats) fully specify the … … type ctype = 61 63 | Tvoid (**r the [void] type *) 62 64 | Tint of intsize*signedness (**r integer types *) 63 65 | Tfloat of floatsize (**r floating-point types *) 64 | Tpointer of ctype(**r pointer types ([*ty]) *)65 | Tarray of ctype*int(**r array types ([ty[len]]) *)66 | Tpointer of memory_space * ctype (**r pointer types ([*ty]) *) 67 | Tarray of memory_space * ctype*int (**r array types ([ty[len]]) *) 66 68 | Tfunction of ctype list*ctype (**r function types *) 67 69 | Tstruct of ident*(ident*ctype) list 68 70 (**r struct types *) … … type init_data = 199 201 type program = { 200 202 prog_funct: (ident * fundef) list ; 201 203 prog_main: ident; 202 prog_vars: (( ident * init_data list) * ctype) list204 prog_vars: (((ident * init_data list) * memory_space) * ctype) list 203 205 } -
src/clight/clightFromC.ml
diff --git a/src/clight/clightFromC.ml b/src/clight/clightFromC.ml index 0aacbce..0a4b947 100644
a b let rec alignof = function 19 19 | Tfloat F32 -> 4 20 20 | Tfloat F64 -> 8 21 21 | Tpointer _ -> 4 22 | Tarray ( t',n) -> alignof t'22 | Tarray (_,t',n) -> alignof t' 23 23 | Tfunction (_,_) -> 1 24 24 | Tstruct (_,fld) -> alignof_fields fld 25 25 | Tunion (_,fld) -> alignof_fields fld … … let rec sizeof t = 42 42 | Tfloat F32 -> 4 43 43 | Tfloat F64 -> 8 44 44 | Tpointer _ -> 4 45 | Tarray ( t',n) -> sizeof t' * max 1 n45 | Tarray (_,t',n) -> sizeof t' * max 1 n 46 46 | Tfunction (_,_) -> 1 47 47 | Tstruct (_,fld) -> align (max 1 (sizeof_struct fld 0)) (alignof t) 48 48 | Tunion (_,fld) -> align (max 1 (sizeof_union fld)) (alignof t) … … let name_for_string_literal env s = 102 102 Hashtbl.add decl_atom id 103 103 (env, (C.Storage_static, 104 104 Env.fresh_ident name, 105 C.TPtr(C. TInt(C.IChar,[C.AConst]),[]),105 C.TPtr(C.Any,C.TInt(C.IChar,[C.AConst]),[]), 106 106 None)); 107 107 !define_stringlit_hook id; 108 108 Hashtbl.add stringTable s id; 109 109 id 110 110 111 111 let typeStringLiteral s = 112 Tarray( Tint(I8, Unsigned), String.length s + 1)112 Tarray(Code, Tint(I8, Unsigned), String.length s + 1) 113 113 114 114 let global_for_string s id = 115 115 let init = ref [] in … … let global_for_string s id = 119 119 :: !init in 120 120 add_char '\000'; 121 121 for i = String.length s - 1 downto 0 do add_char s.[i] done; 122 (( id, !init), typeStringLiteral s)122 (((id, !init), Code), typeStringLiteral s) 123 123 124 124 let globals_for_strings globs = 125 125 Hashtbl.fold … … let register_stub_function name tres targs = 143 143 let rec types_of_types = function 144 144 | [] -> [] 145 145 | Tfloat(_)::tl -> Tfloat(F64)::(types_of_types tl) 146 | _::tl -> Tpointer( Tvoid)::(types_of_types tl) in146 | _::tl -> Tpointer(Any,Tvoid)::(types_of_types tl) in 147 147 let stub_type = Tfunction (types_of_types targs, tres) in 148 148 Hashtbl.add stub_function_table stub_name stub_type; 149 149 (stub_name, stub_type) … … let convertFkind = function 193 193 if not !ClightFlags.option_flonglong then unsupported "'long double' type"; 194 194 F64 195 195 196 let convertSpace = function 197 | C.Any -> Any 198 | C.Data -> Data 199 | C.IData -> IData 200 | C.PData -> PData 201 | C.XData -> XData 202 | C.Code -> Code 203 196 204 let convertTyp env t = 197 205 198 206 let rec convertTyp seen t = … … let convertTyp env t = 202 210 let (sg, sz) = convertIkind ik in Tint(sz, sg) 203 211 | C.TFloat(fk, a) -> 204 212 Tfloat(convertFkind fk) 205 | C.TPtr( C.TStruct(id, _), _) when List.mem id seen ->213 | C.TPtr(_,C.TStruct(id, _), _) when List.mem id seen -> 206 214 Tcomp_ptr("struct " ^ id.name) 207 | C.TPtr( C.TUnion(id, _), _) when List.mem id seen ->215 | C.TPtr(_,C.TUnion(id, _), _) when List.mem id seen -> 208 216 Tcomp_ptr("union " ^ id.name) 209 | C.TPtr( ty, a) ->210 Tpointer(convert Typ seen ty)211 | C.TArray( ty, None, a) ->217 | C.TPtr(sp,ty, a) -> 218 Tpointer(convertSpace sp, convertTyp seen ty) 219 | C.TArray(sp, ty, None, a) -> 212 220 (* Cparser verified that the type ty[] occurs only in 213 221 contexts that are safe for Clight, so just treat as ty[0]. *) 214 222 (* warning "array type of unspecified size"; *) 215 Tarray(convert Typ seen ty, 0)216 | C.TArray( ty, Some sz, a) ->217 Tarray(convert Typ seen ty, convertInt sz )223 Tarray(convertSpace sp, convertTyp seen ty, 0) 224 | C.TArray(sp, ty, Some sz, a) -> 225 Tarray(convertSpace sp, convertTyp seen ty, convertInt sz ) 218 226 | C.TFun(tres, targs, va, a) -> 219 227 if va then unsupported "variadic function type"; 220 228 if Cutil.is_composite_type env tres then … … let rec convertExpr env e = 298 306 let e1' = convertExpr env e1 in 299 307 let ty1 = 300 308 match typeof e1' with 301 | Tpointer t-> t309 | Tpointer (_,t) -> t 302 310 | _ -> error ("wrong type for ->" ^ id ^ " access"); Tvoid in 303 311 Expr(Efield(Expr(Ederef(convertExpr env e1), ty1), 304 312 id), ty) … … let rec convertExpr env e = 315 323 316 324 | C.EBinop(C.Oindex, e1, e2, _) -> 317 325 Expr(Ederef(Expr(Ebinop(Oadd, convertExpr env e1, convertExpr env e2), 318 Tpointer ty)), ty)326 convertTyp env e1.etyp)), ty) 319 327 | C.EBinop(C.Ologand, e1, e2, _) -> 320 328 Expr(Eandbool(convertExpr env e1, convertExpr env e2), ty) 321 329 | C.EBinop(C.Ologor, e1, e2, _) -> … … let rec convertExpr env e = 354 362 let rec projFunType env ty = 355 363 match Cutil.unroll env ty with 356 364 | TFun(res, args, vararg, attr) -> Some(res, vararg) 357 | TPtr( ty', attr) -> projFunType env ty'365 | TPtr(_, ty', attr) -> projFunType env ty' 358 366 | _ -> None 359 367 360 368 let convertFuncall env lhs fn args = … … let volatile_fun_suffix_type ty = 400 408 | Tfloat F32 -> ("float32", ty) 401 409 | Tfloat F64 -> ("float64", ty) 402 410 | Tpointer _ | Tarray _ | Tfunction _ | Tcomp_ptr _ -> 403 ("pointer", Tpointer Tvoid)411 ("pointer", Tpointer (Any, Tvoid)) (* XXX: what is the pointer is to a different space? *) 404 412 | _ -> 405 413 unsupported "operation on volatile struct or union"; ("", Tvoid) 406 414 407 415 let volatile_read_fun ty = 408 416 let (suffix, ty') = volatile_fun_suffix_type ty in 409 417 Expr(Evar( ("__builtin_volatile_read_" ^ suffix)), 410 Tfunction((Tpointer Tvoid)::[], ty'))418 Tfunction((Tpointer (Any,Tvoid))::[], ty')) 411 419 412 420 let volatile_write_fun ty = 413 421 let (suffix, ty') = volatile_fun_suffix_type ty in 414 422 Expr(Evar( ("__builtin_volatile_write_" ^ suffix)), 415 Tfunction((Tpointer Tvoid)::(ty'::[]), Tvoid))423 Tfunction((Tpointer (Any,Tvoid))::(ty'::[]), Tvoid)) 416 424 417 425 (* Toplevel expression, argument of an Sdo *) 418 426 … … let convertTopExpr env e = 432 440 | false, true -> (* volatile read *) 433 441 Scall(Some lhs', 434 442 volatile_read_fun (typeof rhs'), 435 [ Expr (Eaddrof rhs', Tpointer ( typeof rhs')) ])443 [ Expr (Eaddrof rhs', Tpointer (Any (* XXX ? *), typeof rhs')) ]) 436 444 | true, false -> (* volatile write *) 437 445 Scall(None, 438 446 volatile_write_fun (typeof lhs'), 439 [ Expr(Eaddrof lhs', Tpointer ( typeof lhs')); rhs' ])447 [ Expr(Eaddrof lhs', Tpointer (Any (* XXX ? *), typeof lhs')); rhs' ]) 440 448 | false, false -> (* regular assignment *) 441 449 Sassign(convertExpr env lhs, convertExpr env rhs) 442 450 end … … let convertInit env ty init = 663 671 | Init_array il -> 664 672 let ty_elt = 665 673 match Cutil.unroll env ty with 666 | C.TArray( t, _, _) -> t674 | C.TArray(_, t, _, _) -> t 667 675 | _ -> error "array type expected in initializer"; C.TVoid [] in 668 676 List.iter (cvtInit ty_elt) il 669 677 | Init_struct(_, flds) -> … … let convertInit env ty init = 690 698 691 699 (** Global variable *) 692 700 693 let convertGlobvar env (sto, id, ty, optinit as decl) =701 let convertGlobvar env space (sto, id, ty, optinit as decl) = 694 702 let id' = id.name in 695 703 let ty' = convertTyp env ty in 696 704 let init' = … … let convertGlobvar env (sto, id, ty, optinit as decl) = 701 709 convertInit env ty i in 702 710 Hashtbl.add decl_atom id' (env, decl); 703 711 !define_variable_hook id' decl; 704 (( id', init'), ty')712 (((id', init'), convertSpace space), ty') 705 713 706 714 (** Convert a list of global declarations. 707 715 Result is a pair [(funs, vars)] where [funs] are … … let rec convertGlobdecls env funs vars gl = 714 722 | g :: gl' -> 715 723 updateLoc g.gloc; 716 724 match g.gdesc with 717 | C.Gdecl( (sto, id, ty, optinit) as d) ->725 | C.Gdecl(space, ((sto, id, ty, optinit) as d)) -> 718 726 (* Prototyped functions become external declarations. 719 727 Variadic functions are skipped. 720 728 Other types become variable declarations. *) … … let rec convertGlobdecls env funs vars gl = 727 735 | TFun(_, _, true, _) -> 728 736 convertGlobdecls env funs vars gl' 729 737 | _ -> 730 convertGlobdecls env funs (convertGlobvar env d :: vars) gl'738 convertGlobdecls env funs (convertGlobvar env space d :: vars) gl' 731 739 end 732 740 | C.Gfundef fd -> 733 741 convertGlobdecls env (convertFundef env fd :: funs) vars gl' … … let cleanupGlobals p = 769 777 | g :: gl -> 770 778 updateLoc g.gloc; 771 779 match g.gdesc with 772 | C.Gdecl( sto, id, ty, None) ->780 | C.Gdecl(_, (sto, id, ty, None)) -> 773 781 if IdentSet.mem id defs 774 782 then clean defs accu gl 775 783 else clean (IdentSet.add id defs) (g :: accu) gl 776 | C.Gdecl(_, id, ty, _) ->784 | C.Gdecl(_, (_, id, ty, _)) -> 777 785 if IdentSet.mem id defs then 778 786 error ("multiple definitions of " ^ id.name); 779 787 clean (IdentSet.add id defs) (g :: accu) gl … … let rec type_is_readonly env t = 815 823 if List.mem C.AVolatile a then false else 816 824 if List.mem C.AConst a then true else 817 825 match Cutil.unroll env t with 818 | C.TArray( t', _, _) -> type_is_readonly env t'826 | C.TArray(_, t', _, _) -> type_is_readonly env t' 819 827 | _ -> false 820 828 821 829 let atom_is_static a = … … open Builtins 853 861 let builtins_generic = { 854 862 typedefs = [ 855 863 (* keeps GCC-specific headers happy, harmless for others *) 856 "__builtin_va_list", C.TPtr(C. TVoid [], [])864 "__builtin_va_list", C.TPtr(C.Any, C.TVoid [], []) 857 865 ]; 858 866 functions = [ 859 867 (* The volatile read/volatile write functions *) 860 868 "__builtin_volatile_read_int8unsigned", 861 (TInt(IUChar, []), [TPtr( TVoid [], [])], false);869 (TInt(IUChar, []), [TPtr(C.Any, TVoid [], [])], false); 862 870 "__builtin_volatile_read_int8signed", 863 (TInt(ISChar, []), [TPtr( TVoid [], [])], false);871 (TInt(ISChar, []), [TPtr(C.Any, TVoid [], [])], false); 864 872 "__builtin_volatile_read_int16unsigned", 865 (TInt(IUShort, []), [TPtr( TVoid [], [])], false);873 (TInt(IUShort, []), [TPtr(C.Any, TVoid [], [])], false); 866 874 "__builtin_volatile_read_int16signed", 867 (TInt(IShort, []), [TPtr( TVoid [], [])], false);875 (TInt(IShort, []), [TPtr(C.Any, TVoid [], [])], false); 868 876 "__builtin_volatile_read_int32", 869 (TInt(IInt, []), [TPtr( TVoid [], [])], false);877 (TInt(IInt, []), [TPtr(C.Any, TVoid [], [])], false); 870 878 "__builtin_volatile_read_float32", 871 (TFloat(FFloat, []), [TPtr( TVoid [], [])], false);879 (TFloat(FFloat, []), [TPtr(C.Any, TVoid [], [])], false); 872 880 "__builtin_volatile_read_float64", 873 (TFloat(FDouble, []), [TPtr( TVoid [], [])], false);881 (TFloat(FDouble, []), [TPtr(C.Any, TVoid [], [])], false); 874 882 "__builtin_volatile_read_pointer", 875 (TPtr( TVoid [], []), [TPtr(TVoid [], [])], false);883 (TPtr(C.Any, TVoid [], []), [TPtr(C.Any, TVoid [], [])], false); 876 884 "__builtin_volatile_write_int8unsigned", 877 (TVoid [], [TPtr( TVoid [], []); TInt(IUChar, [])], false);885 (TVoid [], [TPtr(C.Any, TVoid [], []); TInt(IUChar, [])], false); 878 886 "__builtin_volatile_write_int8signed", 879 (TVoid [], [TPtr( TVoid [], []); TInt(ISChar, [])], false);887 (TVoid [], [TPtr(C.Any, TVoid [], []); TInt(ISChar, [])], false); 880 888 "__builtin_volatile_write_int16unsigned", 881 (TVoid [], [TPtr( TVoid [], []); TInt(IUShort, [])], false);889 (TVoid [], [TPtr(C.Any, TVoid [], []); TInt(IUShort, [])], false); 882 890 "__builtin_volatile_write_int16signed", 883 (TVoid [], [TPtr( TVoid [], []); TInt(IShort, [])], false);891 (TVoid [], [TPtr(C.Any, TVoid [], []); TInt(IShort, [])], false); 884 892 "__builtin_volatile_write_int32", 885 (TVoid [], [TPtr( TVoid [], []); TInt(IInt, [])], false);893 (TVoid [], [TPtr(C.Any, TVoid [], []); TInt(IInt, [])], false); 886 894 "__builtin_volatile_write_float32", 887 (TVoid [], [TPtr( TVoid [], []); TFloat(FFloat, [])], false);895 (TVoid [], [TPtr(C.Any, TVoid [], []); TFloat(FFloat, [])], false); 888 896 "__builtin_volatile_write_float64", 889 (TVoid [], [TPtr( TVoid [], []); TFloat(FDouble, [])], false);897 (TVoid [], [TPtr(C.Any, TVoid [], []); TFloat(FDouble, [])], false); 890 898 "__builtin_volatile_write_pointer", 891 (TVoid [], [TPtr( TVoid [], []); TPtr(TVoid [], [])], false)899 (TVoid [], [TPtr(C.Any, TVoid [], []); TPtr(C.Any, TVoid [], [])], false) 892 900 ] 893 901 } 894 902 -
src/clight/clightInterpret.ml
diff --git a/src/clight/clightInterpret.ml b/src/clight/clightInterpret.ml index 32b9884..b744932 100644
a b let rec sizeof = function 29 29 | Tfloat F32 -> 4 30 30 | Tfloat F64 -> 8 31 31 | Tpointer _ -> 4 32 | Tarray (_,_)-> 432 | Tarray _ -> 4 33 33 | Tfunction (_,_) -> assert false 34 34 | Tstruct (_,_) -> assert false 35 35 | Tunion (_,_) -> assert false … … let rec mq_of_ty = function 46 46 | Tfloat F32 -> assert false 47 47 | Tfloat F64 -> Memory.MQ_float64 48 48 | Tpointer _ -> Memory.MQ_int32 49 | Tarray ( c,s) -> Memory.MQ_int3249 | Tarray (_,c,s) -> Memory.MQ_int32 50 50 | Tfunction (_,_) -> assert false 51 51 | Tstruct (_,_) -> assert false 52 52 | Tunion (_,_) -> assert false … … let eval_cast = function 207 207 | (Value.Val_float f,_,Tfloat F64) -> Value.Val_float f 208 208 (* Cast pointeur *) 209 209 | (Value.Val_ptr (b,o),_,Tpointer _) -> Value.Val_ptr (b,o) 210 | (Value.Val_ptr (b,o),_,Tarray (_,_)) -> Value.Val_ptr (b,o)210 | (Value.Val_ptr (b,o),_,Tarray _) -> Value.Val_ptr (b,o) 211 211 (* no cast *) 212 212 | (e,a,b) when a=b -> e 213 213 (* error *) … … let eval_add = function 232 232 Value.Val_int (cast_int (i1+i2) t1) 233 233 | ((Value.Val_float i1,Tfloat F64) , (Value.Val_float i2,Tfloat F64)) -> 234 234 Value.Val_float (i1+.i2) 235 | ((Value.Val_int i,_) , (Value.Val_ptr (b,o),Tarray( t,_))) ->235 | ((Value.Val_int i,_) , (Value.Val_ptr (b,o),Tarray(_,t,_))) -> 236 236 Value.Val_ptr (b,o+(i*(sizeof t))) 237 | ((Value.Val_ptr (b,o),Tarray( t,_)) , (Value.Val_int i,_)) ->237 | ((Value.Val_ptr (b,o),Tarray(_,t,_)) , (Value.Val_int i,_)) -> 238 238 Value.Val_ptr (b,o+(i*(sizeof t))) 239 | ((Value.Val_int i,_) , (Value.Val_ptr (b,o),Tpointer t)) ->239 | ((Value.Val_int i,_) , (Value.Val_ptr (b,o),Tpointer (_,t))) -> 240 240 Value.Val_ptr (b,o+(i*(sizeof t))) 241 | ((Value.Val_ptr (b,o),Tpointer t) , (Value.Val_int i,_)) ->241 | ((Value.Val_ptr (b,o),Tpointer (_,t)) , (Value.Val_int i,_)) -> 242 242 Value.Val_ptr (b,o+(i*(sizeof t))) 243 243 | ((v1,_),(v2,_)) -> 244 244 print_string ("Debug: add "^(Value.string_of_value v1)^" with " … … let eval_sub = function 250 250 Value.Val_int (cast_int (i1-i2) t1) 251 251 | ((Value.Val_float i1,Tfloat F64) , (Value.Val_float i2,Tfloat F64)) -> 252 252 Value.Val_float (i1-.i2) 253 | ((Value.Val_int i,_) , (Value.Val_ptr (b,o),Tarray( t,_))) ->253 | ((Value.Val_int i,_) , (Value.Val_ptr (b,o),Tarray(_,t,_))) -> 254 254 Value.Val_ptr (b,o-(i*(sizeof t))) 255 | ((Value.Val_ptr (b,o),Tarray( t,_)) , (Value.Val_int i,_)) ->255 | ((Value.Val_ptr (b,o),Tarray(_,t,_)) , (Value.Val_int i,_)) -> 256 256 Value.Val_ptr (b,o-(i*(sizeof t))) 257 | ((Value.Val_int i,_) , (Value.Val_ptr (b,o),Tpointer t)) ->257 | ((Value.Val_int i,_) , (Value.Val_ptr (b,o),Tpointer (_,t))) -> 258 258 Value.Val_ptr (b,o-(i*(sizeof t))) 259 | ((Value.Val_ptr (b,o),Tpointer t) , (Value.Val_int i,_)) ->259 | ((Value.Val_ptr (b,o),Tpointer (_,t)) , (Value.Val_int i,_)) -> 260 260 Value.Val_ptr (b,o-(i*(sizeof t))) 261 261 | _ -> assert false 262 262 … … let bind_parameters m (param_l:(ident*ctype) list) (arg_l:Value.t list) (var_l:( 475 475 | _ -> assert false 476 476 and treat_v (m,e) = function 477 477 | [] -> (m,e) 478 | (id,Tarray( c,n))::l ->478 | (id,Tarray(s,c,n))::l -> 479 479 (match alloc m 0 (n*(sizeof c)) with 480 | Some(b,m') -> treat_v (bind m' e (id,Tarray( c,n)) (Value.Val_ptr(b,0)) ) l480 | Some(b,m') -> treat_v (bind m' e (id,Tarray(s,c,n)) (Value.Val_ptr(b,0)) ) l 481 481 | None -> assert false) 482 482 | var::l -> treat_v (bind m e var Value.Val_undef) l 483 483 in treat_v (treat_p (m,(Hashtbl.create 11)) (param_l,arg_l)) var_l -
new file src/clight/clightPrintMatita.ml
diff --git a/src/clight/clightPrintMatita.ml b/src/clight/clightPrintMatita.ml new file mode 100644 index 0000000..948ef87
- + 1 (* *********************************************************************) 2 (* *) 3 (* The Compcert verified compiler *) 4 (* *) 5 (* Xavier Leroy, INRIA Paris-Rocquencourt *) 6 (* *) 7 (* Copyright Institut National de Recherche en Informatique et en *) 8 (* Automatique. All rights reserved. This file is distributed *) 9 (* under the terms of the GNU General Public License as published by *) 10 (* the Free Software Foundation, either version 2 of the License, or *) 11 (* (at your option) any later version. This file is also distributed *) 12 (* under the terms of the INRIA Non-Commercial License Agreement. *) 13 (* *) 14 (* *********************************************************************) 15 16 (** Pretty-printer for Csyntax *) 17 18 open Format 19 open AST 20 open Clight 21 22 (* If there's name hiding this might get us into trouble. *) 23 let ident_map = Hashtbl.create 13;; 24 let ident_next = ref 0;; 25 let id_i n = 26 try Hashtbl.find ident_map n 27 with Not_found -> 28 let i = !ident_next in 29 Hashtbl.add ident_map n i; 30 ident_next := i+1; 31 i 32 let id_s n = string_of_int (id_i n) 33 34 let print_list f fmt l = 35 let rec aux fmt = function 36 | [] -> () 37 | [x] -> f fmt x 38 | h::t -> f fmt h; fprintf fmt ";@ "; aux fmt t 39 in 40 fprintf fmt "@[[%a]@]" aux l 41 42 let name_unop = function 43 | Onotbool -> "Onotbool" 44 | Onotint -> "Onotint" 45 | Oneg -> "Oneg" 46 47 48 let name_binop = function 49 | Oadd -> "Oadd" 50 | Osub -> "Osub" 51 | Omul -> "Omul" 52 | Odiv -> "Odiv" 53 | Omod -> "Omod" 54 | Oand -> "Oand" 55 | Oor -> "Oor" 56 | Oxor -> "Oxor" 57 | Oshl -> "Oshl" 58 | Oshr -> "Oshr" 59 | Oeq -> "Oeq" 60 | One -> "One" 61 | Olt -> "Olt" 62 | Ogt -> "Ogt" 63 | Ole -> "Ole" 64 | Oge -> "Oge" 65 66 let name_inttype sz sg = 67 match sz, sg with 68 | I8, Signed -> "I8 Signed " 69 | I8, Unsigned -> "I8 Unsigned " 70 | I16, Signed -> "I16 Signed " 71 | I16, Unsigned -> "I16 Unsigned" 72 | I32, Signed -> "I32 Signed " 73 | I32, Unsigned -> "I32 Unsigned" 74 75 let name_floattype sz = 76 match sz with 77 | F32 -> "F32" 78 | F64 -> "F64" 79 80 (* Collecting the names and fields of structs and unions *) 81 82 module StructUnionSet = Set.Make(struct 83 type t = string * (ident*ctype) list 84 let compare (n1, _ : t) (n2, _ : t) = compare n1 n2 85 end) 86 87 let struct_unions = ref StructUnionSet.empty 88 89 let register_struct_union id fld = 90 struct_unions := StructUnionSet.add (id, fld) !struct_unions 91 92 (* Declarator (identifier + type) *) 93 94 let name_optid id = 95 if id = "" then "" else " " ^ id 96 97 let parenthesize_if_pointer id = 98 if String.length id > 0 && id.[0] = '*' then "(" ^ id ^ ")" else id 99 100 let rec name_cdecl id ty = 101 match ty with 102 | Tvoid -> 103 "void" ^ name_optid id 104 | Tint(sz, sg) -> 105 name_inttype sz sg ^ name_optid id 106 | Tfloat sz -> 107 name_floattype sz ^ name_optid id 108 | Tpointer (s,t) -> (* XXX *) 109 name_cdecl ("*" ^ id) t 110 | Tarray(s, t, n) -> (* XXX *) 111 name_cdecl 112 (sprintf "%s[%d]" (parenthesize_if_pointer id) n) 113 t 114 | Tfunction(args, res) -> 115 let b = Buffer.create 20 in 116 if id = "" 117 then Buffer.add_string b "(*)" 118 else Buffer.add_string b (parenthesize_if_pointer id); 119 Buffer.add_char b '('; 120 begin match args with 121 | [] -> 122 Buffer.add_string b "void" 123 | _ -> 124 let rec add_args first = function 125 | [] -> () 126 | t1::tl -> 127 if not first then Buffer.add_string b ", "; 128 Buffer.add_string b (name_cdecl "" t1); 129 add_args false tl in 130 add_args true args 131 end; 132 Buffer.add_char b ')'; 133 name_cdecl (Buffer.contents b) res 134 | Tstruct(name, fld) -> 135 name ^ name_optid id 136 | Tunion(name, fld) -> 137 name ^ name_optid id 138 | Tcomp_ptr name -> 139 name ^ " *" ^ id 140 141 (* Type *) 142 143 let sspace = function 144 | Any -> "Any" 145 | Data -> "Data" 146 | IData -> "IData" 147 | PData -> "PData" 148 | XData -> "XData" 149 | Code -> "Code" 150 151 let rec stype ty = 152 match ty with 153 | Tvoid -> "Tvoid" 154 | Tint(sz, sg) -> "(Tint " ^ name_inttype sz sg ^ ")" 155 | Tfloat sz -> "(Tfloat " ^ name_floattype sz ^ ")" 156 | Tpointer (sp, t) -> "(Tpointer " ^ sspace sp ^ " " ^ stype t ^ ")" 157 | Tarray(sp, t, n) -> "(Tarray " ^ sspace sp ^ " " ^ stype t ^ " " ^ (string_of_int n) ^ ")" 158 | Tfunction(args, res) -> "(Tfunction " ^ typelist args ^ " " ^ stype res ^ ")" 159 | Tstruct(name, fld) -> 160 fieldlist "(Tstruct (succ_pos_of_nat " name fld 161 | Tunion(name, fld) -> 162 fieldlist "(Tunion (succ_pos_of_nat " name fld 163 | Tcomp_ptr name -> 164 "(Tcomp_ptr (succ_pos_of_nat " ^ id_s name ^ "))" 165 and typelist l = 166 let b = Buffer.create 20 in 167 let rec add_types = function 168 | [] -> Buffer.add_string b "Tnil" 169 | t1::tl -> 170 Buffer.add_string b "(Tcons "; 171 Buffer.add_string b (stype t1); 172 Buffer.add_char b ' '; 173 add_types tl; 174 Buffer.add_char b ')' 175 in add_types l; 176 Buffer.contents b 177 and fieldlist s name l = 178 let b = Buffer.create 20 in 179 Buffer.add_string b s; 180 Buffer.add_string b (id_s name); 181 Buffer.add_string b ") "; 182 let rec add_fields = function 183 | [] -> Buffer.add_string b "Fnil" 184 | (id, ty)::tl -> 185 Buffer.add_string b "(Fcons (succ_pos_of_nat "; 186 Buffer.add_string b (id_s id); 187 Buffer.add_string b ") "; 188 Buffer.add_string b (stype ty); 189 Buffer.add_char b ' '; 190 add_fields tl; 191 Buffer.add_char b ')' 192 in add_fields l; 193 Buffer.add_char b ')'; 194 Buffer.contents b 195 196 let name_type ty = name_cdecl "" ty 197 198 (* Expressions *) 199 200 let rec print_expr p (Expr (eb, ty)) = 201 fprintf p "@[<hov 2>(Expr %a@ %s)@]" print_expr_descr eb (stype ty) 202 and print_expr_descr p eb = 203 match eb with 204 | Ecost (_, Expr (e, _)) -> print_expr_descr p e 205 | Econst_int n -> 206 fprintf p "(Econst_int (repr %d))" n 207 | Econst_float f -> 208 fprintf p "(Econst_float %F)" f 209 | Evar id -> 210 fprintf p "(Evar (succ_pos_of_nat %d))" (id_i id) 211 | Eunop(op, e1) -> 212 fprintf p "(Eunop %s %a)" (name_unop op) print_expr e1 213 | Ederef e -> 214 fprintf p "(Ederef@ %a)" print_expr e 215 | Eaddrof e -> 216 fprintf p "(Eaddrof@ %a)" print_expr e 217 | Ebinop(op, e1, e2) -> 218 fprintf p "(Ebinop@ %s@ %a@ %a)" 219 (name_binop op) 220 print_expr e1 221 print_expr e2 222 | Ecast(ty, e1) -> 223 fprintf p "(Ecast %s@ %a)" 224 (stype ty) 225 print_expr e1 226 | Econdition(e1, e2, e3) -> 227 fprintf p "(Econdition %a@ %a@ %a)" 228 print_expr e1 229 print_expr e2 230 print_expr e3 231 | Eandbool(e1, e2) -> 232 fprintf p "(Eandbool %a@ %a)" 233 print_expr e1 234 print_expr e2 235 | Eorbool(e1, e2) -> 236 fprintf p "(Eorbool %a@ %a)" 237 print_expr e1 238 print_expr e2 239 | Esizeof ty -> 240 fprintf p "(Esizeof %s)" (stype ty) 241 | Efield(e1, id) -> 242 fprintf p "(Efield %a (succ_pos_of_nat %i))" print_expr e1 (id_i id) 243 244 let rec print_expr_list p (first, el) = 245 match el with 246 | [] -> () 247 | e1 :: et -> 248 if not first then fprintf p ",@ "; 249 print_expr p e1; 250 print_expr_list p (false, et) 251 252 let rec print_stmt p s = 253 match s with 254 | Scost (_, s') -> print_stmt p s' 255 | Sskip -> 256 fprintf p "Sskip" 257 | Sassign(e1, e2) -> 258 fprintf p "@[<hv 2>(Sassign %a@ %a)@]" print_expr e1 print_expr e2 259 | Scall(None, e1, el) -> 260 fprintf p "@[<hv 2>(Scall (None ?) %a @[<hov 0>%a@])@]" 261 print_expr e1 262 (print_list print_expr) el 263 | Scall(Some lhs, e1, el) -> 264 fprintf p "@[<hv 2>(Scall (Some ? %a)@ %a@ @[<hov 0>%a@])@]" 265 print_expr lhs 266 print_expr e1 267 (print_list print_expr) el 268 | Ssequence(s1, s2) -> 269 fprintf p "(Ssequence@ %a@ %a)" print_stmt s1 print_stmt s2 270 | Sifthenelse(e, s1, s2) -> 271 fprintf p "@[<v 2>(Sifthenelse %a@ %a@ %a)@]" 272 print_expr e 273 print_stmt s1 274 print_stmt s2 275 | Swhile(e, s) -> 276 fprintf p "@[<v 2>(Swhile %a@ %a)@]" 277 print_expr e 278 print_stmt s 279 | Sdowhile(e, s) -> 280 fprintf p "@[<v 2>S(dowhile %a@ %a)@]" 281 print_expr e 282 print_stmt s 283 | Sfor(s_init, e, s_iter, s_body) -> 284 fprintf p "@[<v 2>(Sfor %a@ %a@ %a@\n%a@;<0 -2>)@]" 285 print_stmt s_init 286 print_expr e 287 print_stmt s_iter 288 print_stmt s_body 289 | Sbreak -> 290 fprintf p "Sbreak" 291 | Scontinue -> 292 fprintf p "Scontinue" 293 | Sswitch(e, cases) -> 294 fprintf p "@[<v 2>(Sswitch %a (@ %a@;<0 -2>))@]" 295 print_expr e 296 print_cases cases 297 | Sreturn None -> 298 fprintf p "(Sreturn (None ?))" 299 | Sreturn (Some e) -> 300 fprintf p "(Sreturn (Some ? %a))" print_expr e 301 | Slabel(lbl, s1) -> 302 fprintf p "(Slabel (succ_pos_of_nat %i)@ %a)" (id_i lbl) print_stmt s1 303 | Sgoto lbl -> 304 fprintf p "(Sgoto (succ_pos_of_nat %i))" (id_i lbl) 305 306 and print_cases p cases = 307 match cases with 308 | LSdefault s -> 309 fprintf p "@[<v 2>(LSdefault@ %a)@]" print_stmt s 310 | LScase(lbl, s, rem) -> 311 fprintf p "@[<v 2>(LScase (repr %d)@ %a@ %a)@]" 312 lbl 313 print_stmt s 314 print_cases rem 315 316 let name_function_parameters params = 317 let b = Buffer.create 20 in 318 Buffer.add_char b '['; 319 let rec add_params first = function 320 | [] -> () 321 | (id, ty) :: rem -> 322 if not first then Buffer.add_string b "; "; 323 Buffer.add_string b "mk_pair ?? (succ_pos_of_nat "; 324 Buffer.add_string b (id_s id); 325 Buffer.add_string b ") "; 326 Buffer.add_string b (stype ty); 327 add_params false rem in 328 add_params true params; 329 Buffer.add_char b ']'; 330 Buffer.contents b 331 332 let print_function p f = 333 fprintf p "@[<v 2>mk_function %s %s %s@ " (stype f.fn_return) 334 (name_function_parameters f.fn_params) 335 (name_function_parameters f.fn_vars); 336 print_stmt p f.fn_body; 337 fprintf p "@;<0 -2>@]@ @ " 338 339 let print_fundef p (id, fd) = 340 fprintf p "@[<v 2>mk_pair ?? (succ_pos_of_nat %i (* %s *)) " (id_i id) id; 341 match fd with 342 | External(id', args, res) -> 343 fprintf p "(External (succ_pos_of_nat %i) %s %s)@]" (id_i id) (typelist args) (stype res) 344 | Internal f -> 345 fprintf p "(Internal (@ %a@;<0 -2>))@]" print_function f 346 347 let string_of_init id = 348 let b = Buffer.create (List.length id) in 349 let add_init = function 350 | Init_int8 c -> 351 if c >= 32 && c <= 126 && c <> Char.code '\"' && c <> Char.code '\\' 352 then Buffer.add_char b (Char.chr c) 353 else Buffer.add_string b (Printf.sprintf "\\%03o" c) 354 | _ -> 355 assert false 356 in List.iter add_init id; Buffer.contents b 357 358 let chop_last_nul id = 359 match List.rev id with 360 | Init_int8 0 :: tl -> List.rev tl 361 | _ -> id 362 363 let print_init p = function 364 | Init_int8 n -> fprintf p "(Init_int8 (repr %d))@ " n 365 | Init_int16 n -> fprintf p "(Init_int16 (repr %d))@ " n 366 | Init_int32 n -> fprintf p "(Init_int32 (repr %d))@ " n 367 | Init_float32 n -> fprintf p "(Init_float32 %F)@ " n 368 | Init_float64 n -> fprintf p "(Iinit_float64 %F)@ " n 369 | Init_space n -> fprintf p "(Init_space %d)@ " n 370 | Init_addrof(symb, ofs) -> fprintf p "(Init_addrof %d (repr %d))" (id_i symb) ofs 371 372 let re_string_literal = Str.regexp "__stringlit_[0-9]+" 373 374 let print_globvar p ((((id, init), sp), ty)) = 375 fprintf p "@[<hov 2>(mk_pair ?? (mk_pair ?? (mk_pair ?? (succ_pos_of_nat %i (* %s *))@ %a)@ %s)@ %s)@]" 376 (id_i id) 377 id 378 (print_list print_init) init 379 (sspace sp) 380 (stype ty) 381 382 (* Collect struct and union types *) 383 384 let rec collect_type = function 385 | Tvoid -> () 386 | Tint(sz, sg) -> () 387 | Tfloat sz -> () 388 | Tpointer (_,t) -> collect_type t 389 | Tarray(_, t, n) -> collect_type t 390 | Tfunction(args, res) -> List.iter collect_type args; collect_type res 391 | Tstruct(id, fld) -> register_struct_union id fld; List.iter collect_field fld 392 | Tunion(id, fld) -> register_struct_union id fld; List.iter collect_field fld 393 | Tcomp_ptr _ -> () 394 395 and collect_field f = collect_type (snd f) 396 397 let rec collect_expr (Expr(ed, ty)) = 398 match ed with 399 | Ecost (_, e) -> collect_expr e 400 | Econst_int n -> () 401 | Econst_float f -> () 402 | Evar id -> () 403 | Eunop(op, e1) -> collect_expr e1 404 | Ederef e -> collect_expr e 405 | Eaddrof e -> collect_expr e 406 | Ebinop(op, e1, e2) -> collect_expr e1; collect_expr e2 407 | Ecast(ty, e1) -> collect_type ty; collect_expr e1 408 | Econdition(e1, e2, e3) -> collect_expr e1; collect_expr e2; collect_expr e3 409 | Eandbool(e1, e2) -> collect_expr e1; collect_expr e2 410 | Eorbool(e1, e2) -> collect_expr e1; collect_expr e2 411 | Esizeof ty -> collect_type ty 412 | Efield(e1, id) -> collect_expr e1 413 414 let rec collect_expr_list = function 415 | [] -> () 416 | hd :: tl -> collect_expr hd; collect_expr_list tl 417 418 let rec collect_stmt = function 419 | Scost (_, s) -> collect_stmt s 420 | Sskip -> () 421 | Sassign(e1, e2) -> collect_expr e1; collect_expr e2 422 | Scall(None, e1, el) -> collect_expr e1; collect_expr_list el 423 | Scall(Some lhs, e1, el) -> collect_expr lhs; collect_expr e1; collect_expr_list el 424 | Ssequence(s1, s2) -> collect_stmt s1; collect_stmt s2 425 | Sifthenelse(e, s1, s2) -> collect_expr e; collect_stmt s1; collect_stmt s2 426 | Swhile(e, s) -> collect_expr e; collect_stmt s 427 | Sdowhile(e, s) -> collect_stmt s; collect_expr e 428 | Sfor(s_init, e, s_iter, s_body) -> 429 collect_stmt s_init; collect_expr e; 430 collect_stmt s_iter; collect_stmt s_body 431 | Sbreak -> () 432 | Scontinue -> () 433 | Sswitch(e, cases) -> collect_expr e; collect_cases cases 434 | Sreturn None -> () 435 | Sreturn (Some e) -> collect_expr e 436 | Slabel(lbl, s) -> collect_stmt s 437 | Sgoto lbl -> () 438 439 and collect_cases = function 440 | LSdefault s -> collect_stmt s 441 | LScase(lbl, s, rem) -> collect_stmt s; collect_cases rem 442 443 let collect_function f = 444 collect_type f.fn_return; 445 List.iter (fun (id, ty) -> collect_type ty) f.fn_params; 446 List.iter (fun (id, ty) -> collect_type ty) f.fn_vars; 447 collect_stmt f.fn_body 448 449 let collect_fundef (id, fd) = 450 match fd with 451 | External(_, args, res) -> List.iter collect_type args; collect_type res 452 | Internal f -> collect_function f 453 454 let collect_globvar ((id, init), ty) = 455 collect_type ty 456 457 let collect_program p = 458 List.iter collect_globvar p.prog_vars; 459 List.iter collect_fundef p.prog_funct 460 461 let declare_struct_or_union p (name, fld) = 462 fprintf p "%s;@ @ " name 463 464 let print_struct_or_union p (name, fld) = 465 fprintf p "@[<v 2>%s {" name; 466 let rec print_field (id, ty) = 467 fprintf p "@ %s;" (name_cdecl id ty) in 468 List.iter print_field fld; 469 fprintf p "@;<0 -2>};@]@ " 470 471 let print_program p prog = 472 struct_unions := StructUnionSet.empty; 473 collect_program prog; 474 fprintf p "include \"Csyntax.ma\".@\n@\n"; 475 fprintf p "@[<v 2>ndefinition myprog := mk_program fundef type@ "; 476 (* StructUnionSet.iter (declare_struct_or_union p) !struct_unions; 477 StructUnionSet.iter (print_struct_or_union p) !struct_unions;*) 478 print_list print_fundef p prog.prog_funct; 479 fprintf p "@\n(succ_pos_of_nat %i)@\n" (id_i "main"); 480 print_list print_globvar p prog.prog_vars; 481 fprintf p "@;<0 -2>.@]@." 482 483 -
src/clight/clightPrinter.ml
diff --git a/src/clight/clightPrinter.ml b/src/clight/clightPrinter.ml index c458e36..b1efd87 100644
a b open Format 19 19 open AST 20 20 open Clight 21 21 22 let name_space = function 23 | Any -> "" 24 | Data -> "__data " 25 | IData -> "__idata " 26 | PData -> "__pdata " 27 | XData -> "__xdata " 28 | Code -> "__code " 29 30 22 31 let name_unop = function 23 32 | Onotbool -> "!" 24 33 | Onotint -> "~" … … let name_optid id = 77 86 let parenthesize_if_pointer id = 78 87 if String.length id > 0 && id.[0] = '*' then "(" ^ id ^ ")" else id 79 88 80 let rec name_cdecl id ty = 89 (* Use Any for the space when nothing should appear. *) 90 91 let rec name_cdecl sp id ty = 92 let ssp = name_space sp in 81 93 match ty with 82 94 | Tvoid -> 83 "void" ^ name_optid id95 ssp ^ "void" ^ name_optid id 84 96 | Tint(sz, sg) -> 85 name_inttype sz sg ^ name_optid id97 ssp ^ name_inttype sz sg ^ name_optid id 86 98 | Tfloat sz -> 87 name_floattype sz ^ name_optid id 88 | Tpointer t -> 89 name_cdecl ("*" ^ id) t 90 | Tarray(t, n) -> 99 ssp ^ name_floattype sz ^ name_optid id 100 | Tpointer (sp',t) -> 101 name_cdecl sp' ("* " ^ ssp ^ id) t 102 | Tarray(sp', t, n) -> 103 if sp <> sp' then eprintf "Array %s has wrong memory space.\n%!" id; 91 104 name_cdecl 105 sp' 92 106 (sprintf "%s[%ld]" (parenthesize_if_pointer id) (Int32.of_int n)) 93 107 t 94 108 | Tfunction(args, res) -> 95 109 let b = Buffer.create 20 in 110 Buffer.add_string b ssp; 96 111 if id = "" 97 112 then Buffer.add_string b "(*)" 98 113 else Buffer.add_string b (parenthesize_if_pointer id); … … let rec name_cdecl id ty = 105 120 | [] -> () 106 121 | t1::tl -> 107 122 if not first then Buffer.add_string b ", "; 108 Buffer.add_string b (name_cdecl "" t1);123 Buffer.add_string b (name_cdecl Any "" t1); 109 124 add_args false tl in 110 125 add_args true args 111 126 end; 112 127 Buffer.add_char b ')'; 113 name_cdecl (Buffer.contents b) res128 name_cdecl Any (Buffer.contents b) res 114 129 | Tstruct(name, fld) -> 115 name ^ name_optid id130 ssp ^ name ^ name_optid id 116 131 | Tunion(name, fld) -> 117 name ^ name_optid id132 ssp ^ name ^ name_optid id 118 133 | Tcomp_ptr name -> 119 name ^ " *" ^ id134 ssp ^ name ^ " *" ^ id 120 135 121 136 (* Type *) 122 137 123 let name_type ty = name_cdecl "" ty138 let name_type ty = name_cdecl Any "" ty 124 139 125 140 (* Expressions *) 126 141 … … let name_function_parameters fun_name params = 318 333 | [] -> () 319 334 | (id, ty) :: rem -> 320 335 if not first then Buffer.add_string b ", "; 321 Buffer.add_string b (name_cdecl id ty);336 Buffer.add_string b (name_cdecl Any id ty); 322 337 add_params false rem in 323 338 add_params true params 324 339 end; … … let name_function_parameters fun_name params = 327 342 328 343 let print_function p id f = 329 344 fprintf p "%s@ " 330 (name_cdecl (name_function_parameters id f.fn_params) 345 (name_cdecl Any 346 (name_function_parameters id f.fn_params) 331 347 f.fn_return); 332 348 fprintf p "@[<v 2>{@ "; 333 349 List.iter 334 350 (fun ((id, ty)) -> 335 fprintf p "%s;@ " (name_cdecl id ty))351 fprintf p "%s;@ " (name_cdecl Any id ty)) 336 352 f.fn_vars; 337 353 print_stmt p f.fn_body; 338 354 fprintf p "@;<0 -2>}@]@ @ " … … let print_fundef p (id, fd) = 341 357 match fd with 342 358 | External(_, args, res) -> 343 359 fprintf p "extern %s;@ @ " 344 (name_cdecl id (Tfunction(args, res)))360 (name_cdecl Any id (Tfunction(args, res))) 345 361 | Internal f -> 346 362 print_function p id f 347 363 … … let print_init p = function 376 392 377 393 let re_string_literal = Str.regexp "__stringlit_[0-9]+" 378 394 379 let print_globvar p ((( id, init), ty)) =395 let print_globvar p ((((id, init), sp), ty)) = 380 396 match init with 381 397 | [] -> 382 398 fprintf p "extern %s;@ @ " 383 (name_cdecl id ty)399 (name_cdecl sp id ty) 384 400 | [Init_space _] -> 385 401 fprintf p "%s;@ @ " 386 (name_cdecl id ty)402 (name_cdecl sp id ty) 387 403 | _ -> 388 404 fprintf p "@[<hov 2>%s = " 389 (name_cdecl id ty);405 (name_cdecl sp id ty); 390 406 if Str.string_match re_string_literal id 0 391 407 && List.for_all (function Init_int8 _ -> true | _ -> false) init 392 408 then … … let rec collect_type = function 404 420 | Tvoid -> () 405 421 | Tint(sz, sg) -> () 406 422 | Tfloat sz -> () 407 | Tpointer t-> collect_type t408 | Tarray( t, n) -> collect_type t423 | Tpointer (_,t) -> collect_type t 424 | Tarray(_, t, n) -> collect_type t 409 425 | Tfunction(args, res) -> collect_type_list args; collect_type res 410 426 | Tstruct(id, fld) -> register_struct_union id fld; collect_fields fld 411 427 | Tunion(id, fld) -> register_struct_union id fld; collect_fields fld … … let print_struct_or_union p (name, fld) = 491 507 let rec print_fields = function 492 508 | [] -> () 493 509 | (id, ty)::rem -> 494 fprintf p "@ %s;" (name_cdecl id ty);510 fprintf p "@ %s;" (name_cdecl Any id ty); 495 511 print_fields rem in 496 512 print_fields fld; 497 513 fprintf p "@;<0 -2>};@]@ " -
src/clight/clightToCminor.ml
diff --git a/src/clight/clightToCminor.ml b/src/clight/clightToCminor.ml index 956239e..8b76ff8 100644
a b let rec ctype_to_type_return t = match t with 7 7 | Tint (_,_) -> Type_ret Sig_int 8 8 | Tfloat _ -> Type_ret Sig_float 9 9 | Tpointer _ -> Type_ret Sig_int 10 | Tarray (_,_)-> Type_ret Sig_int10 | Tarray _ -> Type_ret Sig_int 11 11 | Tfunction (_,_) | Tstruct (_,_) 12 12 | Tunion (_,_) | Tcomp_ptr _ -> assert false 13 13 … … let rec ctype_to_sig_type t = match t with 15 15 | Tint (_,_) -> Sig_int 16 16 | Tfloat _ -> Sig_float 17 17 | Tpointer _ -> Sig_int 18 | Tarray (_,_)-> Sig_int18 | Tarray _ -> Sig_int 19 19 | Tvoid -> assert false 20 20 | Tfunction (_,_) | Tstruct (_,_)| Tunion (_,_) | Tcomp_ptr _ -> 21 21 assert false … … let rec mq_of_ty = function 31 31 | Tfloat F32 -> assert false 32 32 | Tfloat F64 -> Memory.MQ_float64 33 33 | Tpointer _ -> Memory.MQ_int32 34 | Tarray (c,s)-> Memory.MQ_int3234 | Tarray _ -> Memory.MQ_int32 35 35 | Tfunction (_,_) -> assert false 36 36 | Tstruct (_,_) -> assert false 37 37 | Tunion (_,_) -> assert false … … let rec size_of_ctype t = match t with 59 59 | Tfloat F32 -> 8 60 60 | Tfloat F64 -> 8 61 61 | Tpointer _ -> 4 62 | Tarray ( c,s) -> s*(size_of_ctype c)62 | Tarray (_,c,s) -> s*(size_of_ctype c) 63 63 | Tfunction (_,_) | Tstruct (_,_) | Tunion (_,_) | Tcomp_ptr _ -> 64 64 assert false 65 65 66 66 let rec translate_vars v = 67 let (( id,lst),cty) = v in67 let (((id,lst),space),cty) = v in 68 68 match cty with 69 69 | Tint (_,_) | Tfloat _ | Tpointer _ -> (id,init_data_to_data_rec lst) 70 | Tarray( c,_) -> translate_vars ((id,lst),c)70 | Tarray(_,c,_) -> translate_vars (((id,lst),space),c) 71 71 | Tvoid | Tfunction (_,_) | Tstruct (_,_) | Tunion (_,_) | Tcomp_ptr _ -> 72 72 assert false 73 73 … … let translate_binop t1 e1 t2 e2 = function 95 95 (match (t1,t2) with 96 96 | (Tint(_,_),Tint(_,_)) -> Op2 (Op_add,e1,e2) 97 97 | (Tfloat _,Tfloat _) -> Op2 (Op_addf,e1,e2) 98 | (Tpointer t,Tint(_,_)) ->98 | (Tpointer (_,t),Tint(_,_)) -> 99 99 Op2 (Op_add,e1, Op2 (Op_mul,e2,Cst (Cst_int (size_of_ctype t)))) 100 | (Tint(_,_),Tpointer t) ->100 | (Tint(_,_),Tpointer (_,t)) -> 101 101 Op2 (Op_add,Op2 (Op_mul,e1,Cst (Cst_int (size_of_ctype t))),e2) 102 | (Tarray ( t,_),Tint(_,_)) ->102 | (Tarray (_,t,_),Tint(_,_)) -> 103 103 Op2 (Op_add,e1,Op2 (Op_mul,e2,(Cst (Cst_int (size_of_ctype t))))) 104 | (Tint(_,_),Tarray( t,_)) ->104 | (Tint(_,_),Tarray(_,t,_)) -> 105 105 Op2 (Op_add,e2,Op2 (Op_mul,e1,(Cst (Cst_int (size_of_ctype t))))) 106 106 | _ -> assert false 107 107 ) … … let translate_binop t1 e1 t2 e2 = function 109 109 (match (t1,t2) with 110 110 | (Tint(_,_),Tint(_,_)) -> Op2 (Op_sub,e1,e2) 111 111 | (Tfloat _,Tfloat _) -> Op2 (Op_subf,e1,e2) 112 | (Tpointer t,Tint(_,_)) ->112 | (Tpointer (_,t),Tint(_,_)) -> 113 113 Op2 (Op_sub,e1,Op2 (Op_mul,e2,(Cst (Cst_int (size_of_ctype t))))) 114 | (Tint(_,_),Tpointer t) ->114 | (Tint(_,_),Tpointer (_,t)) -> 115 115 Op2 (Op_sub,Op2 (Op_mul,e1,(Cst (Cst_int (size_of_ctype t)))),e2) 116 | (Tarray ( t,_),Tint(_,_)) ->116 | (Tarray (_,t,_),Tint(_,_)) -> 117 117 Op2 (Op_sub,e1,Op2 (Op_mul,e2,(Cst (Cst_int (size_of_ctype t))))) 118 | (Tint(_,_),Tarray( t,_)) ->118 | (Tint(_,_),Tarray(_,t,_)) -> 119 119 Op2 (Op_sub,e2,Op2 (Op_mul,e1,(Cst (Cst_int (size_of_ctype t))))) 120 120 | _ -> assert false 121 121 ) … … let compute_stack f = 310 310 and stck = ref 0 in 311 311 let treat_var v = match snd v with 312 312 | Tvoid | Tint (_,_) | Tfloat _ | Tpointer _ -> () 313 | Tarray (_,_)->313 | Tarray _ -> 314 314 let size = size_of_ctype (snd v) in 315 315 if size > 0 then ( 316 316 (Hashtbl.add addr_of_id (fst v) !stck); … … let translate_funct globals = function 400 400 | (id,External (i,p,r)) -> (id, F_ext (translate_external i p r)) 401 401 402 402 let translate p = 403 let globals = List.map (fun p -> fst (fst p)) p.prog_vars in403 let globals = List.map (fun p -> fst (fst (fst p))) p.prog_vars in 404 404 {Cminor.vars = List.map translate_vars p.prog_vars; 405 405 Cminor.functs = List.map (translate_funct globals) p.prog_funct; 406 406 Cminor.main = p.prog_main } -
src/common/cminorMemory.ml
diff --git a/src/common/cminorMemory.ml b/src/common/cminorMemory.ml index 1b3e509..813be71 100644
a b let rec sizeof = function 204 204 | Tfloat F32 -> 4 205 205 | Tfloat F64 -> 8 206 206 | Tpointer _ -> 4 207 | Tarray (_,_)-> 4207 | Tarray _ -> 4 208 208 | Tfunction (_,_) -> assert false 209 209 | Tstruct (_,_) -> assert false 210 210 | Tunion (_,_) -> assert false … … let vk_of_init_list = function (*FIXME*) 227 227 let cast t v = v (*TODO*) 228 228 229 229 let init m b lst = function 230 | Tarray ( c,n) ->230 | Tarray (_,c,n) -> 231 231 (match alloc m 0 (n*(sizeof c)) with 232 232 | Some(b',m') -> 233 233 (match store m' Memory.MQ_int32 b 0 (Val_ptr(b',0)) with … … let initmem_clight p = 253 253 let b_of_id = Hashtbl.create 11 254 254 and fd_of_b = Hashtbl.create 11 255 255 and i = ref (-1) in 256 let update_mem m (( id,lst),cty) =256 let update_mem m (((id,lst),_),cty) = 257 257 (match alloc m 0 (sizeof cty) with 258 258 | Some(b,m') -> 259 259 Hashtbl.add b_of_id id b; -
src/languages.ml
diff --git a/src/languages.ml b/src/languages.ml index 4317d19..12ffdd2 100644
a b let save filename ast = 230 230 flush cout; 231 231 close_out cout 232 232 233 let rec find_clight = function 234 | [] -> None 235 | AstClight p :: t -> Some p 236 | _::t -> find_clight t 237 238 let save_matita filename asts = 239 match find_clight asts with 240 | None -> Error.warning "during matita output" "No Clight AST." 241 | Some prog -> begin 242 let output_filename = 243 Misc.SysExt.alternative 244 (Filename.chop_extension filename 245 ^ ".ma") 246 in 247 let cout = open_out output_filename in 248 let fout = Format.formatter_of_out_channel cout in 249 ClightPrintMatita.print_program fout prog; 250 flush cout; 251 close_out cout 252 end 253 233 254 let interpret = function 234 255 | AstClight p -> 235 256 ClightInterpret.interpret true p -
src/languages.mli
diff --git a/src/languages.mli b/src/languages.mli index 3dfc31a..f5d8e45 100644
a b val interpret : ast -> AST.label list 75 75 is deduced from the language of the AST. *) 76 76 val save : string -> ast -> unit 77 77 78 (** [save_matita filename asts] pretty prints the first Clight AST in 79 [asts] in a fresh file whose name is prefixed by [filename] and whose 80 extension is .ma. *) 81 val save_matita : string -> ast list -> unit 82 78 83 (** [from_string s] parses [s] as an intermediate language name. *) 79 84 val from_string : string -> name 80 85 -
src/options.ml
diff --git a/src/options.ml b/src/options.ml index 061f7d0..d47e558 100644
a b let debug_flag = ref false 39 39 let set_debug = (:=) debug_flag 40 40 let is_debug_enabled () = !debug_flag 41 41 42 let matita_output_flag = ref false 43 let is_matita_output_enabled () = !matita_output_flag 44 42 45 let options = OptionsParsing.register [ 43 46 "-s", Arg.String set_source_language, 44 47 " Choose the source language between:"; … … let options = OptionsParsing.register [ 58 61 59 62 "-d", Arg.Set debug_flag, 60 63 " Debugging mode."; 64 65 "-ma", Arg.Set matita_output_flag, 66 " Output matita formatted Clight program."; 61 67 ] -
src/options.mli
diff --git a/src/options.mli b/src/options.mli index 4517400..ec6b020 100644
a b val input_files : unit -> string list 22 22 23 23 (** {2 Verbose mode} *) 24 24 val is_debug_enabled : unit -> bool 25 26 (** {2 Matita output of Clight programs} *) 27 val is_matita_output_enabled : unit -> bool
Note: See TracBrowser
for help on using the repository browser.