I made some progress with this using different kind of Visitors. The
attached ml seems to do what I want (i.e., putting a s1: printf
"hello" at the outter most if and a s2: printf "world" at the inner
most if). I still feel it might have some side effects and
incorrect though --
To summarize I want to change
if (cond1){
if (cond 2) {
something;
if (cond3){
}
}
}
into
printf "hello"
if (cond1){
if (cond 2) {
printf "world"
something;
printf "hello"
if (cond3){
printf"world"
}
}
}
VN -
On Sat, Apr 10, 2010 at 2:27 PM, ThanhVu (Vu) Nguyen
<nguyenthanh...@gmail.com> wrote:
> Hi, I am trying to add a statement s1 outside of an if and another
> statement s2 inside of the if as below
>
> s1;
> if (cond1 && cond2 && cond3){
> s2;
> }
>
> CIL breaks that into multiple nested if's so it will look like
> s1;
> if(cond1){
> if(cond2){
> if (cond3){
> s2;
> }
> }
> }
>
>
> I wrote the following simple code for this purpose but it's not
> correct -- it enters an infinite loop and I think the reason is at the
> line (**problem here**) --- because it adds the new statement s1 to
> the current if stuff ... then Do the children , so again revisit the
> current if stuff .
>
>
> (*check if there's no more if's*)
> let isInnerMostBlock b =
> let isIfTheFirst stmt = match stmt.skind with If(cond,b1,b2,l) ->
> true |_ -> false in
> match b.bstmts with [] -> true |(fst_stmt::_) -> not (isIfTheFirst fst_stmt)
>
> class nestedIfConds () = object
> inherit nopCilVisitor
> val mutable inNestedIf = false
>
> method vstmt s = (
> match s.skind with
> |If(cond,b1,b2,l)-> (
> if inNestedIf = false then (
> debug "Entering if\n";
> inNestedIf <- true;
> let s1 = mkEmptyStmt () in
> s.skind <- Block(mkBlock([s1;{s with labels = []}]))
> (** problem here**)
> );
>
> if (isInnerMostBlock b1) then (
> inNestedIf <- false;
>
> let s2 = mkEmptyStmt () in
> b1.bstmts <- s2::b1.bstmts
> );
> DoChildren
> )
>
>
> |_ -> DoChildren
> )
> end
>
> I am not sure how to do this correctly ? e.g., using different
> Visitor action like ChangeTo or DoChildren Post etc ? I don't think
> DoChildrenPost does what I want because it travels all the ways down
> to if(cond3) and returns back from there. Greatly appreciate all
> the helps !
>
>
>
>
>
> VN -
>
open Printf
open Cil
let isInnerMostBlock b =
let isIfTheFirst stmt =
match stmt.skind with If(cond,b1,b2,l) -> true |_ -> false
in
match b.bstmts with [] -> true |(fst_stmt::_) -> not (isIfTheFirst fst_stmt)
let mkPrintf str =
let fprintf = Lval((Var (makeVarinfo true "fprintf" (TVoid []))), NoOffset) in
let hello_str = Const(CStr(str)) in
let instr = Call(None,fprintf,[hello_str],!currentLoc) in
mkStmtOneInstr(instr)
(* ChangeDoChildrenPost( *)
(* s, *)
(* fun s -> ( *)
(* inNestedIf <- false; *)
(* s(\*mkStmt (Block(mkBlock([s1;{s with labels = []}])))*\) *)
(* ) *)
(* )(\*CDCP*\) *)
(* if isInnerMostBlock b1 then ( *)
(* let s2 = mkPrintf "world" in *)
(* let b1' = mkBlock (s2::b1.bstmts) in *)
(* ChangeTo (If(cond,b1',b2,l)) *)
(* ) *)
(* else DoChildren *)
class nestedIfConds () = object
inherit nopCilVisitor
val mutable inNestedIf = false
method vstmt s = (
match s.skind with
|If(cond,b1,b2,l)-> (
if not inNestedIf then (
inNestedIf <- true;
let s1 = mkPrintf "hello" in
if isInnerMostBlock b1 then (
inNestedIf <- false;
let s2 = mkPrintf "world" in
b1.bstmts <- s2::b1.bstmts
);
ChangeDoChildrenPost(
s, fun s -> (
mkStmt(Block(mkBlock([s1;{s with labels = []}])))
)
)
) else (
if isInnerMostBlock b1 then (
inNestedIf <- false;
let s2 = mkPrintf "world" in
b1.bstmts <- s2::b1.bstmts;
);
DoChildren
)
)
|_ -> DoChildren
)
end
let main () = begin
if Array.length Sys.argv < 2 then begin
printf "usage: vu [file.c]\n" ; exit 1
end ;
Cil.initCIL () ;
let filename = Sys.argv.(1) in
let ast = Frontc.parse filename () in
visitCilFileSameGlobals (new nestedIfConds()) ast;
iterGlobals ast (fun glob -> dumpGlobal defaultCilPrinter stdout glob ; ) ;
exit 0
end
;;
main () ;;
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
CIL-users mailing list
CIL-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/cil-users