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&#174; 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

Reply via email to