- Added metavariable metavariable type.
- Add disjunctions on identifiers in some contexts
- Pretend that & indicates a pointer in -c++ mode
+- Support for new
** Features:
- support transformations on variables (only) in declarations that declare
- reuse typedefs and macros from complete parsing when reparsing the
transformed code
- optimization for an if branch that is just { ... }
+- spatch -control_flow_to_file file.c generates a file file.dot
** Bugfix:
- improved parsing of expressions to allow ... to the right of operators in
graph for all of the functions in a file or for a specific function in a
file. This requires {\tt dot} (http://www.graphviz.org/) and {\tt gv}.}
+\rare{-control\_flow\_to\_file $\langle$file$\rangle$,
+ -control\_flow\_to\_file
+ $\langle$file$\rangle$:$\langle$function$\rangle$}{ Like -control\_flow
+ but just puts the dot output in a file in the {\em current} directory.
+ For PATH/file.c, this produces file:xxx.dot for each (selected) function
+ xxx in PATH/file.c.}
+
\rare{-type\_c $\langle$file$\rangle$}{ Parse a C file and pretty-print a
version including type information.}
match var with
| Some (name, iniopt) ->
(match iniopt with
- | Some (iini, (B.InitExpr e, ii_empty2)) ->
+ | B.ValInit (iini, (B.InitExpr e, ii_empty2)) ->
let local =
match local with
Ast_c.NotLocalDecl -> Ast_c.NotLocalVar
| _, ((B.StatementExpr _,_),_)
| _, ((B.Constructor _,_),_)
| _, ((B.New _,_),_)
+ | _, ((B.Delete _,_),_)
-> fail
*)
| A.TyDecl (tya0, ptvirga),
- ({B.v_namei = Some (nameidb, None);
+ ({B.v_namei = Some (nameidb, B.NoInit);
B.v_type = typb0;
B.v_storage = (B.StoTypedef, inl);
B.v_local = local;
return (
(A.TyDecl (tya0, ptvirga)) +> A.rewrap decla,
- (({B.v_namei = Some (nameidb, None);
+ (({B.v_namei = Some (nameidb, B.NoInit);
B.v_type = typb0;
B.v_storage = (B.StoTypedef, inl);
B.v_local = local;
return (
(A.TyDecl (tya0, ptvirga)) +> A.rewrap decla,
- (({B.v_namei = Some (nameidb, None);
+ (({B.v_namei = Some (nameidb, B.NoInit);
B.v_type = typb0;
B.v_storage = (B.StoTypedef, inl);
B.v_local = local;
(* could handle iso here but handled in standard.iso *)
| A.UnInit (stoa, typa, ida, ptvirga),
- ({B.v_namei = Some (nameidb, None);
+ ({B.v_namei = Some (nameidb, B.NoInit);
B.v_type = typb;
B.v_storage = stob;
B.v_local = local;
(fun stoa (stob, iistob) ->
return (
(A.UnInit (stoa, typa, ida, ptvirga)) +> A.rewrap decla,
- (({B.v_namei = Some (nameidb, None);
+ (({B.v_namei = Some (nameidb, B.NoInit);
B.v_type = typb;
B.v_storage = stob;
B.v_local = local;
)))))
| A.Init (stoa, typa, ida, eqa, inia, ptvirga),
- ({B.v_namei = Some(nameidb, Some (iieqb, inib));
+ ({B.v_namei = Some(nameidb, B.ValInit (iieqb, inib));
B.v_type = typb;
B.v_storage = stob;
B.v_local = local;
initialiser inia inib >>= (fun inia inib ->
return (
(A.Init (stoa, typa, ida, eqa, inia, ptvirga)) +> A.rewrap decla,
- (({B.v_namei = Some(nameidb, Some (iieqb, inib));
+ (({B.v_namei = Some(nameidb, B.ValInit (iieqb, inib));
B.v_type = typb;
B.v_storage = stob;
B.v_local = local;
iiptvirgb,iistob)
)))))))
+ | A.Init (stoa, typa, ida, eqa, inia, ptvirga),
+ ({B.v_namei = Some(nameidb, B.ConstrInit _);
+ B.v_type = typb;
+ B.v_storage = stob;
+ B.v_local = local;
+ B.v_attr = attrs;
+ B.v_type_bis = typbbis;
+ },iivirg)
+ -> fail (* C++ constructor declaration not supported in SmPL *)
+
(* do iso-by-absence here ? allow typedecl and var ? *)
| A.TyDecl (typa, ptvirga),
({B.v_namei = None; B.v_type = typb;
| A.Typedef (stoa, typa, ida, ptvirga),
- ({B.v_namei = Some (nameidb, None);
+ ({B.v_namei = Some (nameidb, B.NoInit);
B.v_type = typb;
B.v_storage = (B.StoTypedef,inline);
B.v_local = local;
) >>= (fun ida nameidb ->
return (
(A.Typedef (stoa, typa, ida, ptvirga)) +> A.rewrap decla,
- (({B.v_namei = Some (nameidb, None);
+ (({B.v_namei = Some (nameidb, B.NoInit);
B.v_type = typb;
B.v_storage = (B.StoTypedef,inline);
B.v_local = local;
let iisto = [] in
let stob = B.NoSto, false in
let fake_var =
- ({B.v_namei = Some (nameidb, None);
+ ({B.v_namei = Some (nameidb, B.NoInit);
B.v_type = typb;
B.v_storage = stob;
B.v_local = Ast_c.NotLocalDecl;
(fun fa (var,iiptvirgb,iisto) ->
match fake_var with
- | ({B.v_namei = Some (nameidb, None);
+ | ({B.v_namei = Some (nameidb, B.NoInit);
B.v_type = typb;
B.v_storage = stob;
}, iivirg) ->
-let version = "0.2.5-rc6"
+let version = "0.2.5-rc7"
let path =
try (Sys.getenv "COCCINELLE_HOME")
(* for C++: *)
| New of argument
+ | Delete of expression
(* cppext: IfdefExpr TODO *)
- (* cppext: normmally just expression *)
+ (* cppext: normally just expression *)
and argument = (expression, weird_argument) Common.either
and weird_argument =
| ArgType of parameterType
| MacroDecl of (string * argument wrap2 list) wrap (* fakestart *)
and onedecl =
- { v_namei: (name * (info (* = *) * initialiser) option) option;
+ { v_namei: (name * v_init) option;
v_type: fullType;
(* semantic: set in type annotated and used in cocci_vs_c
* when we transform some initialisation into affectation
v_local: local_decl; (* cocci: *)
v_attr: attribute list; (* gccext: *)
}
+ and v_init =
+ NoInit | ValInit of info * initialiser
+ | ConstrInit of argument wrap2 (* , *) list wrap
and storage = storagebis * bool (* gccext: inline or not *)
and storagebis = NoSto | StoTypedef | Sto of storageClass
and storageClass = Auto | Static | Register | Extern
]
let cpp_keyword_table = Common.hash_of_list [
- "new", (fun ii -> Tnew ii) ]
+ "new", (fun ii -> Tnew ii);
+ "delete",(fun ii -> Tdelete ii) ]
let error_radix s =
("numeric " ^ s ^ " constant contains digits beyond the radix:")
TIdent (s, info)
}
| (letter | '$') (letter | digit | '$') *
+ ('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>') ?
("::~" (letter | '$') (letter | digit | '$') *
('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>') ?) +
raise
(Lexical "~ and :: not allowed in C identifiers, try -c++ option")
}
+ | ((letter | '$') (letter | digit | '$') *)
+ ('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>')
+
+ {
+ if !Flag.c_plus_plus
+ then
+ begin
+ let info = tokinfo lexbuf in
+ let s = tok lexbuf in
+ TypedefIdent (s, info)
+ end
+ else raise (Lexical "<> detected, try -c++ option")
+ }
+
+
| (((letter | '$') (letter | digit | '$') *) as first)
+ ('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>') ?
"::" (((letter | '$') (letter | digit | '$') *) as second)
('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>') ?
("::" ((letter | '$') (letter | digit | '$') *)
(Lexical "~ and :: not allowed in C identifiers, try -c++ option")
}
+ | "::" ((letter | '$') (letter | digit | '$') *)
+ ('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>') ?
+ ("::" ((letter | '$') (letter | digit | '$') *)
+ ('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>') ?) *
+
+ {
+ if !Flag.c_plus_plus
+ then
+ begin
+ let info = tokinfo lexbuf in
+ let s = tok lexbuf in
+ TIdent (s, info)
+ end
+ else
+ raise
+ (Lexical "~ and :: not allowed in C identifiers, try -c++ option")
+ }
+
(* ----------------------------------------------------------------------- *)
(* C constant *)
Tstruct Tunion Tenum
Tbreak Telse Tswitch Tcase Tcontinue Tfor Tdo Tif Twhile Treturn
Tgoto Tdefault
- Tsizeof Tnew
+ Tsizeof Tnew Tdelete TOParCplusplusInit
/*(* C99 *)*/
%token <Ast_c.info>
| Tsizeof unary_expr { mk_e(SizeOfExpr ($2)) [$1] }
| Tsizeof topar2 type_name tcpar2 { mk_e(SizeOfType ($3)) [$1;$2;$4] }
| Tnew new_argument { mk_e(New $2) [$1] }
+ | Tdelete cast_expr { mk_e(Delete $2) [$1] }
new_argument:
- | postfix_expr { Left $1 }
- | decl_spec
- { let ((returnType,hasreg), iihasreg) = fixDeclSpecForParam $1 in
+ | TIdent TOPar argument_list_ne TCPar
+ { let fn = mk_e(Ident (RegularName (mk_string_wrap $1))) [] in
+ Left (mk_e(FunCall (fn, $3)) [$2;$4]) }
+ | TIdent TOPar TCPar
+ { let fn = mk_e(Ident (RegularName (mk_string_wrap $1))) [] in
+ Left(mk_e(FunCall (fn, [])) [$2;$3]) }
+ | TypedefIdent TOPar argument_list_ne TCPar
+ { let fn = mk_e(Ident (RegularName (mk_string_wrap $1))) [] in
+ Left (mk_e(FunCall (fn, $3)) [$2;$4]) }
+ | TypedefIdent TOPar TCPar
+ { let fn = mk_e(Ident (RegularName (mk_string_wrap $1))) [] in
+ Left (mk_e(FunCall (fn, [])) [$2;$3]) }
+ | type_spec
+ { let ty = addTypeD ($1,nullDecl) in
+ let ((returnType,hasreg), iihasreg) = fixDeclSpecForParam ty in
Right (ArgType { p_namei = None; p_type = returnType;
p_register = hasreg, iihasreg;
} )
}
+ | new_argument TOCro expr TCCro
+ {
+ match $1 with
+ Left(e) -> Left(mk_e(ArrayAccess (e, $3)) [$2;$4])
+ | Right(ArgType(ty)) -> (* lots of hacks to make the right type *)
+ let fty = mk_ty (Array (Some $3, ty.Ast_c.p_type)) [$2;$4] in
+ let pty = { ty with p_type = fty } in
+ Right(ArgType pty)
+ | _ -> raise Impossible
+ }
unary_op:
| TAnd { GetRef, $1 }
| topar2 type_name tcpar2 TOBrace initialize_list gcc_comma_opt TCBrace
{ mk_e(Constructor ($2, List.rev $5)) ([$1;$3;$4;$7] ++ $6) }
+
primary_expr:
| identifier_cpp { mk_e(Ident ($1)) [] }
| TInt
DeclList (
($2 +> List.map (fun ((((name,f),attrs), ini), iivirg) ->
let s = str_of_name name in
- let iniopt =
- match ini with
- | None -> None
- | Some (ini, iini) -> Some (iini, ini)
- in
if fst (unwrap storage) =*= StoTypedef
then LP.add_typedef s;
- {v_namei = Some (name, iniopt);
+ {v_namei = Some (name, ini);
v_type = f returnType;
v_storage = unwrap storage;
v_local = local;
/*(* declarators (right part of type and variable) *)*/
/*(*-----------------------------------------------------------------------*)*/
init_declarator2:
- | declaratori { ($1, None) }
- | declaratori teq initialize { ($1, Some ($3, $2)) }
-
+ | declaratori { ($1, NoInit) }
+ | declaratori teq initialize { ($1, ValInit($2, $3)) }
+ /* C++ only */
+ | declaratori TOParCplusplusInit argument_list TCPar
+ { ($1, ConstrInit($3,[$2;$4])) }
/*(*----------------------------*)*/
* because it would compute msg_typedef at compile time when
* the flag debug_typedef is always false
*)
-let msg_typedef s =
+let msg_typedef s n =
incr Stat.nTypedefInfer;
msg_gen (!Flag_parsing_c.debug_typedef)
is_known_typdef
(fun s ->
- pr2_cpp ("TYPEDEF: promoting: " ^ s)
+ (*pr2_cpp (Printf.sprintf "TYPEDEF: promoting(%d): %s" n s)*)
+ pr2_cpp (Printf.sprintf "TYPEDEF: promoting: %s" s)
)
s
match (next, before) with
+ (* c++ hacks *)
+ (* yy xx( and in function *)
+ | TOPar i1::_, TIdent(s,i2)::TypedefIdent _::_
+ when !Flag.c_plus_plus && (LP.current_context () = (LP.InFunction)) ->
+ pr2_cpp("constructed_object: " ^s);
+ TOParCplusplusInit i1
+ | TypedefIdent(s,i)::TOPar i1::_,_
+ when !Flag.c_plus_plus && (LP.current_context () = (LP.InFunction)) ->
+ TIdent(s,i)
+
(*-------------------------------------------------------------*)
(* typedef inference, parse_typedef_fix3 *)
(*-------------------------------------------------------------*)
LP.disable_typedef();
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 1; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* xx yy *)
->
(* && not_annot s2 BUT lead to false positive*)
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 2; LP.add_typedef_root s;
TypedefIdent (s, i1)
| (TIdent (s, i1)::Tinline i2::_ , _) when not_struct_enum before
&& ok_typedef s
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 3; LP.add_typedef_root s;
TypedefIdent (s, i1)
when not_struct_enum before && (LP.current_context() =*= LP.InParameter)
&& ok_typedef s
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 4; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* xx* [,)] *)
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
&& ok_typedef s
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 5; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
&& ok_typedef s
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 6; LP.add_typedef_root s;
TypedefIdent (s, i1)
&& ok_typedef s
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 7; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* xx const *)
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 8; LP.add_typedef_root s;
TypedefIdent (s, i1)
->
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 9; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* ( const xx) *)
| (TIdent (s, i1)::TCPar _::_, (Tconst _ | Tvolatile _|Trestrict _)::TOPar _::_) when
ok_typedef s ->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 10; LP.add_typedef_root s;
TypedefIdent (s, i1)
when not_struct_enum before
&& ok_typedef s
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 11; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* [(,] xx [ AND parameterdeclaration *)
when (LP.current_context() =*= LP.InParameter)
&& ok_typedef s
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 12; LP.add_typedef_root s;
TypedefIdent (s, i1)
(*------------------------------------------------------------*)
(Tregister _|Tstatic _ |Tvolatile _|Tconst _|Trestrict _)::_) when
pointer ptr && ok_typedef s
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 13; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* TODO xx * yy ; AND in start of compound element *)
&& pointer ptr && ok_typedef s
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 14; LP.add_typedef_root s;
TypedefIdent (s, i1)
when not_struct_enum before && pointer ptr &&
(LP.is_top_or_struct (LP.current_context ()))
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 15; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* xx * yy , AND in Toplevel *)
&& ok_typedef s && pointer ptr
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 16; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* xx * yy ( AND in Toplevel *)
&& (LP.is_top_or_struct (LP.current_context ()))
&& ok_typedef s && pointer ptr
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 17; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* xx * yy [ *)
(LP.is_top_or_struct (LP.current_context ()))
&& ok_typedef s && pointer ptr
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 18; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* u16: 10; in struct *)
when (LP.is_top_or_struct (LP.current_context ()))
&& ok_typedef s
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 19; LP.add_typedef_root s;
TypedefIdent (s, i1)
(take_safe 1 !passed_tok <> [Tenum]))
&&
!LP._lexer_hint = Some LP.Toplevel ->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 20; LP.add_typedef_root s;
TypedefIdent s
*)
when not_struct_enum before
&& ok_typedef s && pointer ptr
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 21; LP.add_typedef_root s;
TypedefIdent (s, i1)
when not_struct_enum before && (LP.current_context () =*= LP.InParameter)
&& ok_typedef s && pointer ptr
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 22; LP.add_typedef_root s;
TypedefIdent (s, i1)
(TOBrace _| TPtVirg _)::_) when not_struct_enum before
&& ok_typedef s & pointer ptr
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 23; LP.add_typedef_root s;
msg_maybe_dangereous_typedef s;
TypedefIdent (s, i1)
(TOBrace _| TPtVirg _)::_) when
ok_typedef s && pointer ptr
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 24; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* struct user_info_t sometimes *)
&& ok_typedef s && pointer ptr
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 25; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* xx ** yy *) (* wrong ? *)
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
&& ok_typedef s
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 26; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* xx *** yy *)
&& ok_typedef s
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 27; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* xx ** ) *)
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
&& ok_typedef s
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 28; LP.add_typedef_root s;
TypedefIdent (s, i1)
&& ok_typedef s
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 29; LP.add_typedef_root s;
(*TOPar info*)
TypedefIdent (s, i1)
when not (TH.is_stuff_taking_parenthized x)
&& ok_typedef s
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 30; LP.add_typedef_root s;
(* TOPar info *)
TypedefIdent (s, i1)
*)
(TOPar info)::(TEq _ |TEqEq _)::_)
when ok_typedef s
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 31; LP.add_typedef_root s;
(* TOPar info *)
TypedefIdent (s, i1)
| (TIdent (s, i1)::ptr::TCPar _::TIdent (s2, i2)::_ , (TOPar info)::_)
when ok_typedef s && pointer ptr
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 32; LP.add_typedef_root s;
(*TOPar info*)
TypedefIdent (s,i1)
when (*s ==~ regexp_typedef && *) not (TH.is_stuff_taking_parenthized x)
&& ok_typedef s
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 33; LP.add_typedef_root s;
TypedefIdent (s, i1)
when not_struct_enum before
&& ok_typedef s
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 34; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* x* ( *y )(params), function pointer 2 *)
when not_struct_enum before
&& ok_typedef s
->
- msg_typedef s; LP.add_typedef_root s;
+ msg_typedef s 35; LP.add_typedef_root s;
TypedefIdent (s, i1)
| ParenExpr (e), [i1;i2] -> pr_elem i1; pp_expression e; pr_elem i2;
- | New (t), [i1] -> pr_elem i1; pp_argument t
+ | New (t), [i1] -> pr_elem i1; pp_argument t
+ | Delete(t), [i1] -> pr_elem i1; pp_expression t
| (Ident (_) | Constant _ | FunCall (_,_) | CondExpr (_,_,_)
| Sequence (_,_)
| ArrayAccess (_,_) | RecordAccess (_,_) | RecordPtAccess (_,_)
| SizeOfExpr (_) | SizeOfType (_) | Cast (_,_)
| StatementExpr (_) | Constructor _
- | ParenExpr (_) | New (_)),_ -> raise Impossible
+ | ParenExpr (_) | New (_) | Delete (_)),_ -> raise Impossible
);
if !Flag_parsing_c.pretty_print_type_info
pp_type_with_ident
(Some (s, iis)) (Some (storage, iisto))
returnType attrs;
- iniopt +> do_option (fun (iini, init) ->
- pr_elem iini;
- pp_init init);
+ (match iniopt with
+ Ast_c.NoInit -> ()
+ | Ast_c.ValInit(iini,init) -> pr_elem iini; pp_init init
+ | Ast_c.ConstrInit((init,[lp;rp])) ->
+ pr_elem lp; pp_arg_list init; pr_elem rp
+ | Ast_c.ConstrInit _ -> raise Impossible)
| None -> pp_type returnType
);
iivirg +> List.iter pr_elem;
pp_type_with_ident_rest
(Some (s, iis)) returnType attrs;
- iniopt +> do_option (fun (iini, init) ->
- pr_elem iini; pp_init init
- );
+ (match iniopt with
+ Ast_c.NoInit -> ()
+ | Ast_c.ValInit(iini,init) -> pr_elem iini; pp_init init
+ | Ast_c.ConstrInit((init,[lp;rp])) ->
+ pr_elem lp; pp_arg_list init; pr_elem rp
+ | Ast_c.ConstrInit _ -> raise Impossible);
| x -> raise Impossible
program +> List.iter (fun (e,_) ->
let toprocess =
match specific_func, e with
- | None, _ -> true
+ | None, Ast_c.Definition (defbis,_) ->
+ Some (Ast_c.str_of_name (defbis.Ast_c.f_name))
| Some s, Ast_c.Definition (defbis,_) ->
- s =$= Ast_c.str_of_name (defbis.Ast_c.f_name)
- | _, _ -> false
+ let nm = Ast_c.str_of_name (defbis.Ast_c.f_name) in
+ if s =$= nm then Some nm else None
+ | _, _ -> None
in
- if toprocess
- then
- (* old: Flow_to_ast.test !Flag.show_flow def *)
- (try
+ match toprocess with
+ None -> ()
+ | Some fn -> (* old: Flow_to_ast.test !Flag.show_flow def *)
+ try
let flow = Ast_to_flow.ast_to_control_flow e in
flow +> do_option (fun flow ->
Ast_to_flow.deadcode_detection flow;
*)
flow
in
- let filename = Filename.temp_file "output" ".dot" in
+ let filename =
+ if launchgv
+ then Filename.temp_file "output" ".dot"
+ else
+ let fl = Filename.chop_extension (Filename.basename file) in
+ fl^":"^fn^".dot" in
Ograph_extended.print_ograph_mutable flow' (filename) launchgv
)
with Ast_to_flow.Error (x) -> Ast_to_flow.report_error x
)
- )
let test_cfg = local_test_cfg true
| Tinline (i) -> i
| Ttypeof (i) -> i
| Tnew (i) -> i
+ | Tdelete (i) -> i
+ | TOParCplusplusInit (i) -> i
| EOF (i) -> i
| Tsizeof (i) -> Tsizeof (f i)
| Tasm (i) -> Tasm (f i)
| Tattribute (i) -> Tattribute (f i)
- | TattributeNoarg (i) -> TattributeNoarg (f i)
+ | TattributeNoarg (i) -> TattributeNoarg (f i)
| Tinline (i) -> Tinline (f i)
| Ttypeof (i) -> Ttypeof (f i)
| Tnew (i) -> Tnew (f i)
+ | Tdelete (i) -> Tdelete (f i)
+ | TOParCplusplusInit (i) -> TOParCplusplusInit (f i)
| EOF (i) -> EOF (f i)
pr2_once "Type annotater:not handling New";
Type_c.noTypeHere (* TODO *)
+ | Delete e ->
+ k expr;
+ pr2_once "Type annotater:not handling Delete";
+ Type_c.noTypeHere (* TODO *)
+
in
Ast_c.set_type_expr expr ty
if need_annotate_body then begin
(* int x = sizeof(x) is legal so need process ini *)
- iniopt +> Common.do_option (fun (info, ini) ->
- Visitor_c.vk_ini bigf ini
- );
+ match iniopt with
+ Ast_c.NoInit -> ()
+ | Ast_c.ValInit(iini,init) -> Visitor_c.vk_ini bigf init
+ | Ast_c.ConstrInit((args,_)) ->
+ args +> List.iter (fun (e,ii) ->
+ Visitor_c.vk_argument bigf e
+ )
end
);
);
| ParenExpr (e) -> exprf e
- | New t -> vk_argument bigf t
+ | New t -> vk_argument bigf t
+ | Delete e -> vk_expr bigf e
in exprf expr
attrs +> List.iter (vk_attribute bigf);
var +> Common.do_option (fun (name, iniopt) ->
vk_name bigf name;
- iniopt +> Common.do_option (fun (info, ini) ->
- iif [info];
- vk_ini bigf ini;
- );
+ (match iniopt with
+ Ast_c.NoInit -> ()
+ | Ast_c.ValInit(iini,init) -> iif [iini]; vk_ini bigf init
+ | Ast_c.ConstrInit((init,ii)) -> iif ii; vk_argument_list bigf init)
)
in f (k, bigf) onedecl
| ParenExpr (e) -> ParenExpr (exprf e)
| New t -> New (vk_argument_s bigf t)
+ | Delete e -> Delete (vk_expr_s bigf e)
in
(e', typ'), (iif ii)
{v_namei =
(var +> map_option (fun (name, iniopt) ->
vk_name_s bigf name,
- iniopt +> map_option (fun (info, init) ->
- vk_info_s bigf info,
- vk_ini_s bigf init
- )));
+ (match iniopt with
+ Ast_c.NoInit -> iniopt
+ | Ast_c.ValInit(iini,init) ->
+ Ast_c.ValInit(vk_info_s bigf iini,vk_ini_s bigf init)
+ | Ast_c.ConstrInit((init,ii)) ->
+ let init =
+ init +> List.map (fun (e,ii) -> vk_argument_s bigf e, iif ii) in
+ Ast_c.ConstrInit((init, List.map (vk_info_s bigf) ii)))
+ ));
v_type = vk_type_s bigf t;
(* !!! dont go in semantic related stuff !!! *)
v_type_bis = tbis;