92
95
(* this cocci_tag can be changed, which is how we can express some program
93
96
* transformations by tagging the tokens involved in this transformation.
95
cocci_tag: (Ast_cocci.mcodekind * metavars_binding) ref;
98
cocci_tag: (Ast_cocci.mcodekind * metavars_binding) option ref;
96
99
(* set in comment_annotater_c.ml *)
97
100
comments_tag: comments_around ref;
103
106
(* wrap2 is like wrap, except that I use it often for separator such
104
107
* as ','. In that case the info is associated to the argument that
105
* follows, so in 'a,b' I will have in the list [(a,[]); (b,[','])]. *)
108
* follows, so in 'a,b' I will have in the list [(a,[]); (b,[','])].
110
* wrap3 is like wrap, except that I use it in case sometimes it
111
* will be empty because the info will be included in a nested
112
* entity (e.g. for Ident in expr because it's inlined in the name)
113
* so user should never assume List.length wrap3 > 0.
106
115
and 'a wrap = 'a * il
107
116
and 'a wrap2 = 'a * il
117
and 'a wrap3 = 'a * il (* * evotype*)
109
119
(* ------------------------------------------------------------------------- *)
113
123
(* was called 'ident' before, but 'name' is I think better
114
124
* as concatenated strings can be used not only for identifiers and for
115
125
* declarators, but also for fields, for labels, etc.
127
* Note: because now the info is embeded in the name, the info for
128
* expression like Ident, or types like Typename, are not anymore
129
* stored in the expression or type. Hence if you assume this,
130
* which was true before, you are now wrong. So never write code like
131
* let (unwrape,_), ii = e and use 'ii' believing it contains
132
* the local ii to e. If you want to do that, use the appropiate
133
* wrapper get_local_ii_of_expr_inlining_ii_of_name.
118
136
| RegularName of string wrap
208
226
(* -------------------------------------- *)
209
227
and structUnion = Struct | Union
210
228
and structType = field list
211
and field = fieldbis wrap
213
230
| DeclarationField of field_declaration
218
| MacroStructDeclTodo
235
| MacroDeclField of (string * argument wrap2 list)
236
wrap (* optional ';'*)
221
239
| CppDirectiveStruct of cpp_directive
265
283
(* ------------------------------------------------------------------------- *)
266
284
(* C expression *)
267
285
(* ------------------------------------------------------------------------- *)
268
and expression = (expressionbis * exp_info ref (* semantic: *)) wrap
286
and expression = (expressionbis * exp_info ref (* semantic: *)) wrap3
269
287
and exp_info = exp_type option * test
270
288
and exp_type = fullType (* Type_c.completed_and_simplified *) * local
271
289
and local = LocalVar of parse_info | NotLocalVar (* cocci: *)
315
333
(* cppext: IfdefExpr TODO *)
317
335
(* cppext: normmally just expression *)
318
and argument = (expression, weird_argument) either
336
and argument = (expression, weird_argument) Common.either
319
337
and weird_argument =
320
338
| ArgType of parameterType
321
339
| ArgAction of action_macro
336
354
| String of (string * isWchar)
337
355
| MultiString of string list (* can contain MacroString, todo: more info *)
338
356
| Char of (string * isWchar) (* normally it is equivalent to Int *)
339
| Int of (string (* * intType*))
357
| Int of (string * intType)
340
358
| Float of (string * floatType)
342
360
and isWchar = IsWchar | IsChar
697
714
and comments_around = {
698
715
mbefore: Token_c.comment_like_token list;
699
716
mafter: Token_c.comment_like_token list;
701
(* old: can do something simpler than CComment for coccinelle, cf above.
702
mbefore: comment_and_relative_pos list;
703
mafter: comment_and_relative_pos list;
718
(* less: could remove ? do something simpler than CComment for
719
* coccinelle, cf above. *)
720
mbefore2: comment_and_relative_pos list;
721
mafter2: comment_and_relative_pos list;
704
723
and comment_and_relative_pos = {
706
725
minfo: Common.parse_info;
736
754
let noInstr = (ExprStatement (None), [])
737
755
let noTypedefDef () = None
740
757
let emptyMetavarsBinding =
741
758
([]: metavars_binding)
760
let emptyAnnotCocci =
744
761
(Ast_cocci.CONTEXT (Ast_cocci.NoPos,Ast_cocci.NOTHING),
745
762
emptyMetavarsBinding)
765
(None: (Ast_cocci.mcodekind * metavars_binding) option)
767
(* compatibility mode *)
768
let mcode_and_env_of_cocciref aref =
771
| None -> emptyAnnotCocci
747
774
let emptyComments= {
782
811
let unwrap2 = fst
785
813
let unwrap_expr ((unwrap_e, typ), iie) = unwrap_e
786
814
let rewrap_expr ((_old_unwrap_e, typ), iie) newe = ((newe, typ), iie)
816
let unwrap_typeC (qu, (typeC, ii)) = typeC
817
let rewrap_typeC (qu, (typeC, ii)) newtypeC = (qu, (newtypeC, ii))
819
let unwrap_typeCbis (typeC, ii) = typeC
821
let unwrap_st (unwrap_st, ii) = unwrap_st
823
(* ------------------------------------------------------------------------- *)
824
let mk_e unwrap_e ii = (unwrap_e, noType()), ii
825
let mk_e_bis unwrap_e ty ii = (unwrap_e, ty), ii
827
let mk_ty typeC ii = nQ, (typeC, ii)
828
let mk_tybis typeC ii = (typeC, ii)
830
let mk_st unwrap_st ii = (unwrap_st, ii)
832
(* ------------------------------------------------------------------------- *)
833
let get_ii_typeC_take_care (typeC, ii) = ii
834
let get_ii_st_take_care (st, ii) = ii
835
let get_ii_expr_take_care (e, ii) = ii
837
let get_st_and_ii (st, ii) = st, ii
838
let get_ty_and_ii (qu, (typeC, ii)) = qu, (typeC, ii)
839
let get_e_and_ii (e, ii) = e, ii
842
(* ------------------------------------------------------------------------- *)
788
843
let get_type_expr ((unwrap_e, typ), iie) = !typ
789
844
let set_type_expr ((unwrap_e, oldtyp), iie) newtyp =
800
855
| Some (ft,local), _test -> Some local
801
856
| None, _ -> None
805
let unwrap_typeC (qu, (typeC, ii)) = typeC
806
let rewrap_typeC (qu, (typeC, ii)) newtypeC = (qu, (newtypeC, ii))
809
858
(* ------------------------------------------------------------------------- *)
810
859
let rewrap_str s ii =
861
912
let line_of_info ii = get_orig_info (function x -> x.Common.line) ii
862
913
let col_of_info ii = get_orig_info (function x -> x.Common.column) ii
863
914
let file_of_info ii = get_orig_info (function x -> x.Common.file) ii
864
let mcode_of_info ii = fst (!(ii.cocci_tag))
915
let mcode_of_info ii = fst (mcode_and_env_of_cocciref ii.cocci_tag)
865
916
let pinfo_of_info ii = ii.pinfo
866
917
let parse_info_of_info ii = get_pi ii.pinfo
973
1024
Common.line = magic_real_number;
974
1025
Common.column = magic_real_number}) in
975
1026
{mbefore = []; (* duplicates mafter of the previous token *)
976
mafter = List.map al_com (keep_cpp x.mafter)}
1027
mafter = List.map al_com (keep_cpp x.mafter);
978
1032
let al_info_cpp tokenindex x =
1044
1098
(* Helpers, could also be put in lib_parsing_c.ml instead *)
1045
1099
(*****************************************************************************)
1047
let rec stmt_elems_of_sequencable xs =
1048
xs +> Common.map (fun x ->
1051
| CppDirectiveStmt _
1054
pr2_once ("stmt_elems_of_sequencable: filter a directive");
1056
| IfdefStmt2 (_ifdef, xxs) ->
1057
pr2 ("stmt_elems_of_sequencable: IfdefStm2 TODO?");
1058
xxs +> List.map (fun xs ->
1059
let xs' = stmt_elems_of_sequencable xs in
1067
1101
(* should maybe be in pretty_print_c ? *)
1069
1103
let s_of_inc_file inc_file =
1100
1136
(xs +> List.map (fun ((x,iix), iicomma) -> x) +> Common.join ",") ^
1103
let info_of_name ident =
1105
| RegularName (s,ii) -> List.hd ii
1139
let get_s_and_ii_of_name name =
1141
| RegularName (s, iis) -> s, iis
1142
| CppIdentBuilder ((s, iis), xs) -> s, iis
1143
| CppVariadicName (s,iis) ->
1144
let (iop, iis) = Common.tuple_of_list2 iis in
1106
1146
| CppConcatenatedName xs ->
1108
1148
| [] -> raise Impossible
1109
| ((x,ii1),ii2)::xs ->
1149
| ((s,iis),noiiop)::xs ->
1112
| CppVariadicName (s, ii) ->
1113
let (iihash, iis) = Common.tuple_of_list2 ii in
1115
| CppIdentBuilder ((s,iis),xs) ->
1118
let get_s_and_ii_of_name name =
1120
| RegularName (s, iis) -> s, List.hd iis
1153
let get_s_and_info_of_name name =
1154
let (s,ii) = get_s_and_ii_of_name name in
1157
let info_of_name name =
1158
let (s,ii) = get_s_and_ii_of_name name in
1161
let ii_of_name name =
1162
let (s,ii) = get_s_and_ii_of_name name in
1167
let get_local_ii_of_expr_inlining_ii_of_name e =
1168
let (ebis,_),ii = e in
1170
| Ident name, noii ->
1173
| RecordAccess (e, name), ii ->
1174
ii @ ii_of_name name
1175
| RecordPtAccess (e, name), ii ->
1176
ii @ ii_of_name name
1180
let get_local_ii_of_tybis_inlining_ii_of_name ty =
1182
| TypeName (name, _typ), [] -> ii_of_name name
1185
(* only Label and Goto have name *)
1186
let get_local_ii_of_st_inlining_ii_of_name st =
1188
| Labeled (Label (name, st)), ii -> ii_of_name name @ ii
1189
| Jump (Goto name), ii ->
1190
let (i1, i3) = Common.tuple_of_list2 ii in
1191
[i1] @ ii_of_name name @ [i3]
1196
(* ------------------------------------------------------------------------- *)
1124
1197
let name_of_parameter param =
1125
1198
param.p_namei +> Common.map_option (str_of_name)