Skip to content

Commit 203f283

Browse files
coslusim642
authored andcommitted
Add C11 generic to Cabs and CIL
Partially cherry-picked from ad69b97.
1 parent 7a912dd commit 203f283

File tree

7 files changed

+72
-0
lines changed

7 files changed

+72
-0
lines changed

src/cil.ml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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 *)
282283
and ikind =
@@ -537,6 +538,7 @@ and exp =
537538
* It is not printed. Given an lval of type
538539
* [TArray(T)] produces an expression of type
539540
* [TPtr(T)]. *)
541+
| Generic of exp * ((typ * exp) list)
540542

541543

542544
(** Literal constants *)
@@ -1526,6 +1528,7 @@ let rec typeAttrs = function
15261528
| TEnum (enum, a) -> addAttributes enum.eattr a
15271529
| TFun (_, _, _, a) -> a
15281530
| TBuiltin_va_list a -> a
1531+
| TDefault -> []
15291532

15301533

15311534
let setTypeAttrs t a =
@@ -1540,6 +1543,7 @@ let setTypeAttrs t a =
15401543
| TEnum (enum, _) -> TEnum (enum, a)
15411544
| TFun (r, args, v, _) -> TFun(r,args,v,a)
15421545
| TBuiltin_va_list _ -> TBuiltin_va_list a
1546+
| TDefault -> TDefault
15431547

15441548

15451549
let typeAddAttributes a0 t =
@@ -1562,6 +1566,7 @@ begin
15621566
| TComp (comp, a) -> TComp (comp, add a)
15631567
| TNamed (t, a) -> TNamed (t, add a)
15641568
| TBuiltin_va_list a -> TBuiltin_va_list (add a)
1569+
| TDefault -> TDefault
15651570
end
15661571

15671572
let typeRemoveAttributes (anl: string list) t =
@@ -1577,6 +1582,7 @@ let typeRemoveAttributes (anl: string list) t =
15771582
| TComp (comp, a) -> TComp (comp, drop a)
15781583
| TNamed (t, a) -> TNamed (t, drop a)
15791584
| TBuiltin_va_list a -> TBuiltin_va_list (drop a)
1585+
| TDefault -> TDefault
15801586

15811587
let unrollType (t: typ) : typ =
15821588
let rec withAttrs (al: attributes) (t: typ) : typ =
@@ -1857,6 +1863,7 @@ let getParenthLevel (e: exp) =
18571863

18581864
| Lval(Var _, NoOffset) -> 0 (* Plain variables *)
18591865
| Const _ -> 0 (* Constants *)
1866+
| Generic _ -> 0 (*TODO*)
18601867

18611868

18621869
let getParenthLevelAttrParam (a: attrparam) =
@@ -1953,6 +1960,7 @@ let rec typeOf (e: exp) : typ =
19531960
TArray (t,_, a) -> TPtr(t, a)
19541961
| _ -> E.s (E.bug "typeOf: StartOf on a non-array")
19551962
end
1963+
| Generic (e, lst) -> match lst with (t, e1) :: rest -> typeOf e1 | _ -> voidType (* TODO: implement properly *)
19561964

19571965
and typeOfInit (i: init) : typ =
19581966
match i with
@@ -2242,6 +2250,7 @@ let rec alignOf_int t =
22422250

22432251
| TFun _ as t -> raise (SizeOfError ("function", t))
22442252
| TVoid _ as t -> raise (SizeOfError ("void", t))
2253+
| TDefault -> raise (SizeOfError ("default", t))
22452254
in
22462255
match filterAttributes "aligned" (typeAttrs t) with
22472256
[] ->
@@ -2554,6 +2563,7 @@ and bitsSizeOf t =
25542563
0
25552564

25562565
| TFun _ -> raise (SizeOfError ("function", t))
2566+
| TDefault -> raise (SizeOfError("default", t))
25572567

25582568

25592569
and addTrailing nrbits roundto =
@@ -2821,6 +2831,8 @@ let rec isConstant = function
28212831
| AddrOf (Mem e, off) | StartOf(Mem e, off)
28222832
-> isConstant e && isConstantOffset off
28232833
| AddrOfLabel _ -> true
2834+
| Generic _ -> false (*TODO*)
2835+
28242836
and isConstantOffset = function
28252837
NoOffset -> true
28262838
| Field(fi, off) -> isConstantOffset off
@@ -3524,6 +3536,14 @@ class defaultCilPrinterClass : cilPrinter = object (self)
35243536

35253537
| StartOf(lv) -> self#pLval () lv
35263538

3539+
| Generic(e, lst) ->
3540+
let rec print_generic_exp l doc =
3541+
match l with
3542+
| [] -> doc
3543+
| (t, e1) :: rest -> print_generic_exp rest (doc ++ text ", " ++ (self#pType None () t) ++ text ":" ++ self#pExp () e1)
3544+
in
3545+
text "_Generic(" ++ self#pExp () e ++ print_generic_exp lst nil ++ text ")"
3546+
35273547
(* Print an expression, given the precedence of the context in which it
35283548
* appears. *)
35293549
method private pExpPrec (contextprec: int) () (e: exp) =
@@ -4460,6 +4480,7 @@ class defaultCilPrinterClass : cilPrinter = object (self)
44604480
++ self#pAttrs () a
44614481
++ text " "
44624482
++ name
4483+
| TDefault -> text "default"
44634484

44644485

44654486
(**** PRINTING ATTRIBUTES *********)
@@ -4795,6 +4816,7 @@ class plainCilPrinterClass =
47954816
end
47964817
| TBuiltin_va_list a ->
47974818
dprintf "TBuiltin_va_list(%a)" self#pAttrs a
4819+
| TDefault -> dprintf "TDefault"
47984820

47994821

48004822
(* Some plain pretty-printers. Unlike the above these expose all the
@@ -4873,6 +4895,13 @@ class plainCilPrinterClass =
48734895
| StartOf lv -> dprintf "StartOf(%a)" self#pLval lv
48744896
| AddrOf (lv) -> dprintf "AddrOf(%a)" self#pLval lv
48754897
| AddrOfLabel (sref) -> dprintf "AddrOfLabel(%a)" self#pStmt !sref
4898+
| Generic(e, lst) ->
4899+
let rec print_generic_exp l doc =
4900+
match l with
4901+
| [] -> doc
4902+
| (t, e1) :: rest -> print_generic_exp rest (doc ++ text "," ++ (self#pType None () t) ++ text ":" ++ self#pExp () e1)
4903+
in
4904+
text "_Generic(" ++ self#pExp () e ++ text "," ++ print_generic_exp lst nil
48764905

48774906

48784907

@@ -5386,6 +5415,8 @@ and childrenExp (vis: cilVisitor) (e: exp) : exp =
53865415
| StartOf lv ->
53875416
let lv' = vLval lv in
53885417
if lv' != lv then StartOf lv' else e
5418+
| Generic(e, lst) -> e (*TODO*)
5419+
53895420

53905421
and visitCilInit (vis: cilVisitor) (forglob: varinfo)
53915422
(atoff: offset) (i: init) : init =
@@ -6170,6 +6201,7 @@ let rec typeSigWithAttrs ?(ignoreSign=false) doattr t =
61706201
TSFun(typeSig rt, (Util.list_map_opt (fun (_, atype, _) -> (typeSig atype)) args), isva, doattr a)
61716202
| TNamed(t, a) -> typeSigAddAttrs (doattr a) (typeSig t.ttype)
61726203
| TBuiltin_va_list al -> TSBase (TBuiltin_va_list (doattr al))
6204+
| TDefault -> TSBase (TDefault)
61736205

61746206
let typeSig t =
61756207
typeSigWithAttrs (fun al -> al) t

src/cil.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ and typ =
242242

243243
| TBuiltin_va_list of attributes
244244
(** This is the same as the gcc's type with the same name *)
245+
| TDefault
245246

246247
(**
247248
There are a number of functions for querying the kind of a type. These are
@@ -631,6 +632,7 @@ and exp =
631632
* not sure which one to use. In C this operation is implicit, the
632633
* [StartOf] operator is not printed. We have it in CIL because it makes
633634
* the typing rules simpler. *)
635+
| Generic of exp * ((typ * exp) list)
634636

635637
(** {b Constants.} *)
636638

src/frontc/cabs.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ type typeSpecifier = (* Merge all specifiers into one type *)
8080
| Tenum of string * enum_item list option * attribute list
8181
| TtypeofE of expression (* GCC __typeof__ *)
8282
| TtypeofT of specifier * decl_type (* GCC __typeof__ *)
83+
| Tdefault
8384

8485
and storage =
8586
NO_STORAGE | AUTO | STATIC | EXTERN | REGISTER
@@ -281,6 +282,7 @@ and expression =
281282
| MEMBEROFPTR of expression * string
282283
| GNU_BODY of block
283284
| EXPR_PATTERN of string (* pattern variable, and name *)
285+
| GENERIC of expression * ((specifier * expression) list)
284286

285287
and constant =
286288
| CONST_INT of string (* the textual representation *)

src/frontc/cabs2cil.ml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,6 +1569,7 @@ let cabsTypeAddAttributes a0 t =
15691569
| TComp (comp, a) -> TComp (comp, addA0To a)
15701570
| TNamed (t, a) -> TNamed (t, addA0To a)
15711571
| TBuiltin_va_list a -> TBuiltin_va_list (addA0To a)
1572+
| TDefault -> TDefault
15721573
end
15731574

15741575

@@ -2458,6 +2459,7 @@ let rec doSpecList (suggestedAnonName: string) (* This string will be part of
24582459
| [A.Tfloat128] -> TFloat(FLongDouble, []) (* TODO: Correct? *)
24592460

24602461
(* Now the other type specifiers *)
2462+
| [A.Tdefault] -> TDefault
24612463
| [A.Tnamed n] -> begin
24622464
if n = "__builtin_va_list" &&
24632465
!Machdep.theMachine.Machdep.__builtin_va_list then begin
@@ -4844,6 +4846,26 @@ and doExp (asconst: bool) (* This expression is used as a constant *)
48444846

48454847
| A.EXPR_PATTERN _ -> E.s (E.bug "EXPR_PATTERN in cabs2cil input")
48464848

4849+
| A.GENERIC (expr, lst) ->
4850+
let get_exp tupel = match tupel with _, e, _ -> e in
4851+
let exp = get_exp (doExp false expr (AExp None)) in
4852+
let rec make_cil_list cabs_l cil_l = match cabs_l with
4853+
| [] -> cil_l
4854+
| (s, e) :: rest -> make_cil_list rest (((doOnlyType s JUSTBASE),get_exp (doExp false e (AExp None))) :: cil_l)
4855+
in
4856+
let cil_list = make_cil_list lst [] in
4857+
let exp_typ = typeOf exp in
4858+
let default_typ = ref voidType in
4859+
let typ =
4860+
let rec get_typ l = match l with
4861+
| (TDefault, e) :: rest -> default_typ := typeOf e; get_typ rest
4862+
| (t, e) :: rest -> if t = exp_typ then typeOf e else get_typ rest
4863+
| [] -> !default_typ
4864+
in
4865+
get_typ cil_list
4866+
in
4867+
finishExp empty (Generic(exp, (make_cil_list lst []))) typ
4868+
48474869
with e when continueOnError -> begin
48484870
(*ignore (E.log "error in doExp (%s)" (Printexc.to_string e));*)
48494871
E.hadErrors := true;

src/frontc/cabsvisit.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,7 @@ and childrenExpression vis e =
538538
let b' = visitCabsBlock vis b in
539539
if b' != b then GNU_BODY b' else e
540540
| EXPR_PATTERN _ -> e
541+
| GENERIC _ -> e (*TODO*)
541542

542543
and visitCabsInitExpression vis (ie: init_expression) : init_expression =
543544
doVisit vis vis#vinitexpr childrenInitExpression ie

src/frontc/clexer.mll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ let init_lexicon _ =
225225
THREAD loc
226226
else
227227
IDENT ("__thread", loc));
228+
("_Generic", fun loc -> GENERIC loc);
228229
]
229230

230231
(* Mark an identifier as a type name. The old mapping is preserved and will

src/frontc/cparser.mly

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ let transformOffsetOf (speclist, dtype) member =
257257
%token EOF
258258
%token<Cabs.cabsloc> CHAR INT BOOL DOUBLE FLOAT VOID INT64 INT32
259259
%token<Cabs.cabsloc> INT128 FLOAT128 COMPLEX /* C99 */
260+
%token<Cabs.cabsloc> GENERIC /* C11 */
260261
%token<Cabs.cabsloc> ENUM STRUCT TYPEDEF UNION
261262
%token<Cabs.cabsloc> SIGNED UNSIGNED LONG SHORT
262263
%token<Cabs.cabsloc> VOLATILE EXTERN STATIC CONST RESTRICT AUTO REGISTER
@@ -475,8 +476,19 @@ primary_expression: /*(* 6.5.1. *)*/
475476
/*(* Next is Scott's transformer *)*/
476477
| AT_EXPR LPAREN IDENT RPAREN /* expression pattern variable */
477478
{ EXPR_PATTERN(fst $3), $1 }
479+
| GENERIC LPAREN assignment_expression COMMA generic_assoc_list RPAREN {GENERIC ((fst $3), $5), $1}
478480
;
479481

482+
/* (specifier, expression) list */
483+
generic_assoc_list:
484+
| generic_association {[$1]}
485+
| generic_assoc_list COMMA generic_association {$3 :: $1}
486+
487+
/* specifier, expression */
488+
generic_association:
489+
| type_name COLON assignment_expression {fst $1, fst $3}
490+
| DEFAULT COLON assignment_expression {[SpecType(Tdefault)], fst $3}
491+
480492
postfix_expression: /*(* 6.5.2 *)*/
481493
| primary_expression
482494
{ $1 }

0 commit comments

Comments
 (0)