Claire, attached is a new .ml version that has some additional code
to check on some special cases (since the original one you gave me
doesn't work with these cases). I feel it might be incorrect or
might have side effects. Could you look at it and let me know if it's
OK ?
thanks
VN -
On Sat, Apr 10, 2010 at 4:21 PM, ThanhVu (Vu) Nguyen
<nguyenthanh...@gmail.com> wrote:
> 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 -
>>
>
int main(){
int a = 1;
int b = 2;
int c = 3;
if (a == c){
printf("1");
}
if (a == b && b ==c || c == a){
printf("1");
if (a == c){
}
}
else{
}
return 0;
}
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