Hi.
     I also needed for one of my CIL modules to access the parent statement of 
a 
statement, but also the parent of the parent, etc. So I follow up this thread 
of discussion.
     You can find a possible implementation of obtaining the parents of AST 
nodes below - 
the code worked well for the few tests that I used. Let me know if you have 
comments.

     A suggestion (this is actually the main reason I wrote this email): the 
ChangeDoChildrenPost is a very useful feature - I used it to build and update 
at the end 
of the visit the stackStmt. Now I wonder if it is worthy to have a simpler 
DoChildrenPost 
that would not have the update part of ChangeDoChildrenPost, but simply execute 
a "Post" 
function after traversing all the children.

   (* Since we do not have access to the parent nodes of each node visited, we
    * keep track of them.
    * Since the CIL visitor performs DFS traversal of the AST, we keep a stack 
of
    * the parent nodes method vstmt visits - stackStmt[0] = parent of current s
    * in stmt, stackStmt[1] = parent of stackStmt[0], etc.
    *)
   val mutable stackStmt : stmt list = []

   method vstmt (s: stmt) : stmt visitAction =
     stackStmt <- s :: stackStmt;
     match s.skind with
       Loop(block, loc, stmt_continue, break_label) ->
         ignore(
           if List.length stackStmt >= 3 then
             let parentStmt = List.hd (List.tl (List.tl stackStmt)) in
             E.log "  parent3 of Loop is %a\n" Cil.d_stmt parentStmt;
         );
         ignore(
           if List.length stackStmt >= 2 then
             let parentStmt = List.hd (List.tl stackStmt) in
             E.log "  parent2 of Loop is %a\n" Cil.d_stmt parentStmt;
         );
         ignore(
           if List.length stackStmt >= 1 then
             let parentStmt = List.hd stackStmt in
             E.log "  parent1 of Loop is %a\n" Cil.d_stmt parentStmt;
         );
         ignore(
           if List.length block.bstmts > 2 then
             let stmt_break = (List.hd (List.tl block.bstmts)) in
             E.log "  stmt_break is %a\n" Cil.d_stmt stmt_break;

           match stmt_break.skind with
             If(exp, then_block, else_block, loc) ->
               E.log "  stmt_break's expression is %a\n" Cil.d_exp exp;
           | _ -> E.log "";
         );

         ChangeDoChildrenPost (s,
             fun x -> (
               ignore(
                 E.log "List.length stackStmt=%d\n" (List.length stackStmt);
                 if List.length stackStmt > 0 then
                   if (List.hd stackStmt) = s then
                     stackStmt <- List.tl stackStmt
               );
               x));
     | _ ->
         ChangeDoChildrenPost (s,
             fun x -> (
               ignore(
                 E.log "List.length stackStmt=%d\n" (List.length stackStmt);
                 if List.length stackStmt > 0 then
                   if (List.hd stackStmt) = s then
                     stackStmt <- List.tl stackStmt
               );
               x));



   Best regards,
     Alex


On 01/28/2006 23:07, Matt Harren wrote:
> Hi Roy,
>
> You can add
>
> val mutable currentStmt: stmt = Cil.dummyStmt
>
> to your visitor class, and
>
> currentStmt <- s;
>
> to your vstmt visitor. Now you can access currentStmt while visiting
> instructions. I frequently do something similar to track the current
> fundec, so that I can use it to make temp vars in the visitor.
>
> -- Matt
>
>
>
>
>  > -----Original Message-----
>  > From: cil-users-admin@...
>  > [mailto:cil-users-admin@...] On Behalf Of Roy
>  > Sent: Wednesday, January 18, 2006 11:19 AM
>  > To: cil-users@...
>  > Subject: [CIL users] Access to Parent Structure
>  >
>  > Howdy,
>  >
>  > I often want to look through the individual instructions of a
>  > program looking for an instruction of interest. Upon finding
>  > such an instruction, I then wish to look at (as an example)
>  > the other instructions in instruction block that forms the
>  > CIL statement containing the instruction of interest.
>  >
>  > This pattern of wanting access to the parent type (stmt) from
>  > a more specialized type (instr) often appears in my code. As
>  > such, a lot of my CIL code uses a custom instr visitor siting
>  > within the stmt visitor, so that I have easy access to the
>  > stmt encompassing an instr. But this seems like a waste.
>  >
>  > Is there a mechanism for accessing a parent type from a more
>  > specialized type in CIL?
>  >
>  > Peace,
>  > -Roy
>  >
>  >
>  >
>  > -------------------------------------------------------
>  > This SF.net email is sponsored by: Splunk Inc. Do you grep
>  > through log files for problems? Stop! Download the new AJAX
>  > search engine that makes searching your log files as easy as
>  > surfing the web. DOWNLOAD SPLUNK!
>  > http://sel.as-us.falkag.net/sel?cmd=lnk&kid=103432&bid=230486&;;
>  > dat=121642
>  > _______________________________________________
>  > CIL-users mailing list
>  > CIL-users@...
>  > https://lists.sourceforge.net/lists/listinfo/cil-users

------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
CIL-users mailing list
CIL-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/cil-users

Reply via email to