@@ -277,6 +277,7 @@ and typ =
277277
278278 | TBuiltin_va_list of attributes
279279 (* * This is the same as the gcc's type with the same name *)
280+ | TDefault
280281
281282(* * Various kinds of integers *)
282283and ikind =
@@ -546,9 +547,12 @@ and exp =
546547 * It is not printed. Given an lval of type
547548 * [TArray(T)] produces an expression of type
548549 * [TPtr(T)]. *)
550+ | Generic of exp * ((typ * exp) list )
549551
550552and wstring_type = | Wchar_t | Char16_t | Char32_t
551553
554+ and encoding = No_encoding | Utf8
555+
552556(* * Literal constants *)
553557and constant =
554558 | CInt64 of int64 * ikind * string option
@@ -557,7 +561,7 @@ and constant =
557561 * {!Cil.integer} or {!Cil.kinteger} to create these. Watch
558562 * out for integers that cannot be represented on 64 bits.
559563 * OCAML does not give Overflow exceptions. *)
560- | CStr of string (* * String constant (of pointer type) *)
564+ | CStr of string * encoding (* * String constant (of pointer type) *)
561565 | CWStr of int64 list * wstring_type (* * Wide string constant (of type "wchar_t *") *)
562566 | CChr of char (* * Character constant. This has type int, so use
563567 * charConstToInt to read the value in case
@@ -1422,7 +1426,7 @@ type attributeClass =
14221426let attributeHash: (string , attributeClass) H. t =
14231427 let table = H. create 13 in
14241428 List. iter (fun a -> H. add table a (AttrName false ))
1425- [ " section" ; " constructor" ; " destructor" ; " unused" ; " used" ; " weak" ;
1429+ [ " section" ; " constructor" ; " destructor" ; " unused" ; " used" ; " weak" ;
14261430 " no_instrument_function" ; " alias" ; " no_check_memory_usage" ;
14271431 " exception" ; " model" ; (* "restrict"; *)
14281432 " aconst" ; " __asm__" (* Gcc uses this to specify the name to be used in
@@ -1436,8 +1440,8 @@ let attributeHash: (string, attributeClass) H.t =
14361440
14371441 List. iter (fun a -> H. add table a (AttrFunType false ))
14381442 [ " format" ; " regparm" ; " longcall" ;
1439- " noinline" ; " always_inline" ; " gnu_inline" ; " leaf" ;
1440- " artificial" ; " warn_unused_result" ; " nonnull" ; " c_noreturn " ;
1443+ " noinline" ; " always_inline" ; " gnu_inline" ; " leaf" ; " c_noreturn " ;
1444+ " artificial" ; " warn_unused_result" ; " nonnull" ;
14411445 ];
14421446
14431447 List. iter (fun a -> H. add table a (AttrFunType true ))
@@ -1532,6 +1536,7 @@ let rec typeAttrs = function
15321536 | TEnum (enum , a ) -> addAttributes enum.eattr a
15331537 | TFun (_ , _ , _ , a ) -> a
15341538 | TBuiltin_va_list a -> a
1539+ | TDefault -> []
15351540
15361541
15371542let setTypeAttrs t a =
@@ -1546,6 +1551,7 @@ let setTypeAttrs t a =
15461551 | TEnum (enum , _ ) -> TEnum (enum, a)
15471552 | TFun (r , args , v , _ ) -> TFun (r,args,v,a)
15481553 | TBuiltin_va_list _ -> TBuiltin_va_list a
1554+ | TDefault -> TDefault
15491555
15501556
15511557let typeAddAttributes a0 t =
@@ -1568,6 +1574,7 @@ begin
15681574 | TComp (comp , a ) -> TComp (comp, add a)
15691575 | TNamed (t , a ) -> TNamed (t, add a)
15701576 | TBuiltin_va_list a -> TBuiltin_va_list (add a)
1577+ | TDefault -> TDefault
15711578end
15721579
15731580let typeRemoveAttributes (anl : string list ) t =
@@ -1583,6 +1590,7 @@ let typeRemoveAttributes (anl: string list) t =
15831590 | TComp (comp , a ) -> TComp (comp, drop a)
15841591 | TNamed (t , a ) -> TNamed (t, drop a)
15851592 | TBuiltin_va_list a -> TBuiltin_va_list (drop a)
1593+ | TDefault -> TDefault
15861594
15871595let unrollType (t : typ ) : typ =
15881596 let rec withAttrs (al : attributes ) (t : typ ) : typ =
@@ -1652,7 +1660,7 @@ let getComplexFkind = function
16521660let var vi : lval = (Var vi, NoOffset )
16531661(* let assign vi e = Instrs(Set (var vi, e), lu) *)
16541662
1655- let mkString s = Const (CStr s )
1663+ let mkString s = Const (CStr (s, No_encoding ) )
16561664
16571665
16581666let mkWhile ~(guard :exp ) ~(body : stmt list ) : stmt list =
@@ -1790,7 +1798,7 @@ let d_const () c =
17901798 text (prefix ^ (Int64. to_string i ^ suffix))
17911799 )
17921800
1793- | CStr (s ) -> text (" \" " ^ escape_string s ^ " \" " )
1801+ | CStr (s , enc ) -> let prefix = match enc with No_encoding -> " " | Utf8 -> " u8 " in text (prefix ^ " \" " ^ escape_string s ^ " \" " )
17941802 | CWStr (s , st ) ->
17951803 (* text ("L\"" ^ escape_string s ^ "\"") *)
17961804 let prefix = match st with Wchar_t -> " L" | Char16_t -> " u" | Char32_t -> " U" in
@@ -1872,6 +1880,7 @@ let getParenthLevel (e: exp) =
18721880
18731881 | Lval (Var _ , NoOffset) -> 0 (* Plain variables *)
18741882 | Const _ -> 0 (* Constants *)
1883+ | Generic _ -> 0 (* TODO*)
18751884
18761885
18771886let getParenthLevelAttrParam (a : attrparam ) =
@@ -1945,7 +1954,7 @@ let rec typeOf (e: exp) : typ =
19451954 (* The type of a string is a pointer to characters ! The only case when
19461955 * you would want it to be an array is as an argument to sizeof, but we
19471956 * have SizeOfStr for that *)
1948- | Const (CStr s ) -> ! stringLiteralType
1957+ | Const (CStr ( _ , _ ) ) -> ! stringLiteralType
19491958
19501959 | Const (CWStr (s ,st )) -> TPtr ((match st with Wchar_t -> ! wcharType | Char16_t -> ! char16Type | Char32_t -> ! char32Type), [] )
19511960
@@ -1968,6 +1977,7 @@ let rec typeOf (e: exp) : typ =
19681977 TArray (t ,_ , a ) -> TPtr (t, a)
19691978 | _ -> E. s (E. bug " typeOf: StartOf on a non-array" )
19701979 end
1980+ | Generic (e , lst ) -> match lst with (t , e1 ) :: rest -> typeOf e1 | _ -> voidType
19711981
19721982and typeOfInit (i : init ) : typ =
19731983 match i with
@@ -2257,6 +2267,7 @@ let rec alignOf_int t =
22572267
22582268 | TFun _ as t -> raise (SizeOfError (" function" , t))
22592269 | TVoid _ as t -> raise (SizeOfError (" void" , t))
2270+ | TDefault -> raise (SizeOfError (" default" , t))
22602271 in
22612272 match filterAttributes " aligned" (typeAttrs t) @ filterAttributes " alignas" (typeAttrs t) with
22622273 [] ->
@@ -2266,25 +2277,46 @@ let rec alignOf_int t =
22662277 ignore (warn " ignoring recursive align attributes on %a"
22672278 (! pd_type) t);
22682279 alignOfType ()
2269- | (Attr(_ , [a ]) as at )::rest -> begin
2270- if rest <> [] then
2271- ignore (warn " ignoring duplicate align attributes on %a"
2272- (! pd_type) t);
2273- match intOfAttrparam a with
2274- | Some 0 -> alignOfType ()
2280+ | (Attr(_ , [a ]) as at )::rest ->
2281+ let is_power_of_two n =
2282+ let log2 = (log10 (float_of_int n)) /. (log10 2. ) in
2283+ ceil log2 = floor log2
2284+ in
2285+ let rec strictest_alignment (current :int ) (lst :attribute list ) =
2286+ match lst with
2287+ [] -> current
2288+ | (Attr(_ , [a ]) as at )::rest -> begin
2289+ match intOfAttrparam a with
2290+ Some 0 -> strictest_alignment current rest
2291+ | Some n ->
2292+ if not (is_power_of_two n) then begin
2293+ ignore(warn " Invalid alignment value specified by attribute %a\n " (! pd_attr) at);
2294+ strictest_alignment current rest
2295+ end
2296+ else strictest_alignment (max current n) rest
2297+ | None ->
2298+ ignore (warn " alignment attribute \" %a\" not understood on %a" (! pd_attr) at (! pd_type) t);
2299+ strictest_alignment current rest
2300+ end
2301+ | Attr (_ , [] ) :: rest ->
2302+ ! M. theMachine.M. alignof_aligned
2303+ | at ::_ ->
2304+ ignore (warn " alignment attribute \" %a\" not understood on %a"
2305+ (! pd_attr) at (! pd_type) t);
2306+ strictest_alignment current rest
2307+ in
2308+ let current = match intOfAttrparam a with
2309+ Some 0 -> alignOfType ()
22752310 | Some n ->
2276- let is_power_of_two n =
2277- let log2 = (log10 (float_of_int n)) /. (log10 2. ) in
2278- ceil log2 = floor log2
2279- in
22802311 if not (is_power_of_two n) then
22812312 alignOfType (ignore(warn " Invalid alignment value specified by attribute %a\n " (! pd_attr) at))
22822313 else n
22832314 | None ->
2284- ignore (warn " alignment attribute \" %a\" not understood on %a"
2285- (! pd_attr) at (! pd_type) t);
2286- alignOfType ()
2287- end
2315+ ignore (warn " alignment attribute \" %a\" not understood on %a"
2316+ (! pd_attr) at (! pd_type) t);
2317+ alignOfType ()
2318+ in
2319+ strictest_alignment current rest
22882320 | Attr (_ , [] )::rest ->
22892321 (* aligned with no arg means a power of two at least as large as
22902322 any alignment on the system.*)
@@ -2579,6 +2611,7 @@ and bitsSizeOf t =
25792611 0
25802612
25812613 | TFun _ -> raise (SizeOfError (" function" , t))
2614+ | TDefault -> raise (SizeOfError (" default" , t))
25822615
25832616
25842617and addTrailing nrbits roundto =
@@ -2856,6 +2889,8 @@ let rec isConstant = function
28562889 | AddrOf (Mem e, off) | StartOf (Mem e, off)
28572890 -> isConstant e && isConstantOffset off
28582891 | AddrOfLabel _ -> true
2892+ | Generic _ -> false (* TODO*)
2893+
28592894and isConstantOffset = function
28602895 NoOffset -> true
28612896 | Field (fi , off ) -> isConstantOffset off
@@ -3535,7 +3570,7 @@ class defaultCilPrinterClass : cilPrinter = object (self)
35353570 | Real e ->
35363571 text " __real__(" ++ self#pExp () e ++ chr ')'
35373572 | SizeOfStr s ->
3538- text " sizeof(" ++ d_const () (CStr s ) ++ chr ')'
3573+ text " sizeof(" ++ d_const () (CStr (s, No_encoding ) ) ++ chr ')'
35393574
35403575 | AlignOf (t ) ->
35413576 text " __alignof__(" ++ self#pType None () t ++ chr ')'
@@ -3563,6 +3598,14 @@ class defaultCilPrinterClass : cilPrinter = object (self)
35633598
35643599 | StartOf (lv ) -> self#pLval () lv
35653600
3601+ | Generic (e , lst ) ->
3602+ let rec print_generic_exp l doc =
3603+ match l with
3604+ | [] -> doc
3605+ | (t , e1 ) :: rest -> print_generic_exp rest (doc ++ text " , " ++ (self#pType None () t) ++ text " :" ++ self#pExp () e1)
3606+ in
3607+ text " _Generic(" ++ self#pExp () e ++ print_generic_exp lst nil ++ text " )"
3608+
35663609 (* Print an expression, given the precedence of the context in which it
35673610 * appears. *)
35683611 method private pExpPrec (contextprec : int ) () (e : exp ) =
@@ -4499,6 +4542,7 @@ class defaultCilPrinterClass : cilPrinter = object (self)
44994542 ++ self#pAttrs () a
45004543 ++ text " "
45014544 ++ name
4545+ | TDefault -> text " default"
45024546
45034547
45044548 (* *** PRINTING ATTRIBUTES *********)
@@ -4842,6 +4886,7 @@ class plainCilPrinterClass =
48424886 end
48434887 | TBuiltin_va_list a ->
48444888 dprintf " TBuiltin_va_list(%a)" self#pAttrs a
4889+ | TDefault -> dprintf " TDefault"
48454890
48464891
48474892 (* Some plain pretty-printers. Unlike the above these expose all the
@@ -4856,8 +4901,9 @@ class plainCilPrinterClass =
48564901 (Int64. format fmt i)
48574902 d_ikind ik
48584903 (match so with Some s -> s | _ -> " None" )
4859- | CStr (s ) ->
4860- text (" CStr(\" " ^ escape_string s ^ " \" )" )
4904+ | CStr (s , enc ) ->
4905+ let enc_string = match enc with No_encoding -> " _" | Utf8 -> " UTF8" in
4906+ text (" CStr(\" " ^ escape_string s ^ " \" ," ^ enc_string ^ " )" )
48614907 | CWStr (s ,_ ) ->
48624908 dprintf " CWStr(%a)" d_const c
48634909
@@ -4908,7 +4954,7 @@ class plainCilPrinterClass =
49084954 | SizeOfE (e ) ->
49094955 text " sizeofE(" ++ self#pExp () e ++ chr ')'
49104956 | SizeOfStr (s ) ->
4911- text " sizeofStr(" ++ d_const () (CStr s ) ++ chr ')'
4957+ text " sizeofStr(" ++ d_const () (CStr (s, No_encoding ) ) ++ chr ')'
49124958 | AlignOf (t ) ->
49134959 text " __alignof__(" ++ self#pType None () t ++ chr ')'
49144960 | AlignOfE (e ) ->
@@ -4924,6 +4970,13 @@ class plainCilPrinterClass =
49244970 | StartOf lv -> dprintf " StartOf(%a)" self#pLval lv
49254971 | AddrOf (lv ) -> dprintf " AddrOf(%a)" self#pLval lv
49264972 | AddrOfLabel (sref ) -> dprintf " AddrOfLabel(%a)" self#pStmt ! sref
4973+ | Generic (e , lst ) ->
4974+ let rec print_generic_exp l doc =
4975+ match l with
4976+ | [] -> doc
4977+ | (t , e1 ) :: rest -> print_generic_exp rest (doc ++ text " ," ++ (self#pType None () t) ++ text " :" ++ self#pExp () e1)
4978+ in
4979+ text " _Generic(" ++ self#pExp () e ++ text " ," ++ print_generic_exp lst nil
49274980
49284981
49294982
@@ -5444,6 +5497,8 @@ and childrenExp (vis: cilVisitor) (e: exp) : exp =
54445497 | StartOf lv ->
54455498 let lv' = vLval lv in
54465499 if lv' != lv then StartOf lv' else e
5500+ | Generic (e , lst ) -> e (* TODO*)
5501+
54475502
54485503and visitCilInit (vis : cilVisitor ) (forglob : varinfo )
54495504 (atoff : offset ) (i : init ) : init =
@@ -6235,6 +6290,7 @@ let rec typeSigWithAttrs ?(ignoreSign=false) doattr t =
62356290 TSFun (typeSig rt, (Util. list_map_opt (fun (_ , atype , _ ) -> (typeSig atype)) args), isva, doattr a)
62366291 | TNamed (t , a ) -> typeSigAddAttrs (doattr a) (typeSig t.ttype)
62376292 | TBuiltin_va_list al -> TSBase (TBuiltin_va_list (doattr al))
6293+ | TDefault -> TSBase (TDefault )
62386294
62396295let typeSig t =
62406296 typeSigWithAttrs (fun al -> al) t
@@ -6262,7 +6318,7 @@ let typeSigAttrs = function
62626318
62636319
62646320let dExp: doc -> exp =
6265- fun d -> Const (CStr (sprint ~width: ! lineLength d))
6321+ fun d -> Const (CStr (sprint ~width: ! lineLength d, No_encoding ))
62666322
62676323let dInstr: doc -> location -> instr =
62686324 fun d l -> Asm ([] , [sprint ~width: ! lineLength d], [] , [] , [] , l)
0 commit comments