<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    Note that the surrounding statement is not necessarily in the same
    block. Say, your algorithm would fail to find full statement 'x ? y
    : z;' by looking at its sub-expression 'y'.<br>
    <br>
    As far as i'm aware, no existing data flow analyses operate the way
    you describe.<br>
    <br>
    <div class="moz-cite-prefix">On 9/8/20 7:15 AM, Andrew Sutton via
      cfe-dev wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAFVAEf2bZRxhQWOKVFEs8DLOZvkNeuo1ZK=A-nA_WoGPW=MzcA@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div dir="ltr">I ran into exactly this problem last week. I wanted
        to visit top-level statements (and expressions since
        expression-statements are just expressions) and recursively work
        through their ASTs. I just wrote a small pre-pass over the CFG
        elements that would construct a set of top-level statements by
        noting which expressions occurred as subexpressions and then
        extract the statements from there.
        <div>
          <div><br>
          </div>
          <div>There's probably a better way to do this, but here's what
            my implementation of that function looks like.<br>
            <div><br>
            </div>
            <div>    void findStatements(CFGBlock *B,
              llvm::SmallVectorImpl<const Stmt *> &SS) {<br>
                    llvm::SmallDenseMap<const Stmt*, bool> Map;<br>
              <br>
                    // Mark subexpressions of each element in the block.<br>
                    for (auto I = B->begin(); I != B->end(); ++I)
              {<br>
                      CFGElement E = *I;<br>
                      if (auto SE = E.getAs<CFGStmt>()) {<br>
                        const Stmt *S = SE->getStmt();<br>
                        for (const Stmt *K : S->children())<br>
                          Map[K] = true;<br>
                      }<br>
                    }<br>
              <br>
                    // Any expressions not in Map are statements.<br>
                    for (auto I = B->begin(); I != B->end(); ++I)
              {<br>
                      CFGElement E = *I;<br>
                      if (auto SE = E.getAs<CFGStmt>()) {<br>
                        const Stmt *S = SE->getStmt();<br>
                        if (Map.find(S) == Map.end())<br>
                          SS.push_back(S);<br>
                      }<br>
                    }<br>
                  }<br>
            </div>
          </div>
        </div>
        <div><br>
        </div>
        <div>Andrew Sutton</div>
        <div><br>
        </div>
      </div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">On Tue, Sep 8, 2020 at 9:44 AM
          Stefan Schulze Frielinghaus via cfe-dev <<a
            href="mailto:cfe-dev@lists.llvm.org" moz-do-not-send="true">cfe-dev@lists.llvm.org</a>>
          wrote:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0px 0px 0px
          0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi
          all,<br>
          <br>
          I'm trying to iterate over all top-level functions of a C file
          and perform<br>
          control-flow analysis of each function body.  My current
          approach looks as<br>
          follows:<br>
          <br>
          class MyASTVisitor : public DeclVisitor<MyASTVisitor> {<br>
            ASTContext &Context;<br>
          public:<br>
            explicit MyASTVisitor(ASTContext &Context) :
          Context(Context) { }<br>
          <br>
            void VisitFunctionDecl(FunctionDecl *FD) {<br>
              if (!FD->hasBody())<br>
                return;<br>
          <br>
              FD->getNameInfo().getName().dump();<br>
          <br>
              const CFG::BuildOptions opts;<br>
              auto CFG = CFG::buildCFG(FD, FD->getBody(),
          &Context, opts);<br>
              CFG->dump(Context.getLangOpts(), true);<br>
              // perform the actual analysis over the CFG<br>
            }<br>
          };<br>
          <br>
          class MyConsumer : public ASTConsumer {<br>
            MyASTVisitor Visitor;<br>
          public:<br>
            explicit MyConsumer(ASTContext &Context) :
          Visitor(Context) { }<br>
          <br>
            bool HandleTopLevelDecl(DeclGroupRef DR) override {<br>
              for (auto *I : DR)<br>
                Visitor.Visit(I);<br>
              return true;<br>
            }<br>
          };<br>
          <br>
          What confuses me right now is how the CFG is structured. 
          Consider the<br>
          following C code:<br>
          <br>
          extern int *pi;<br>
          extern unsigned char *pc;<br>
          void foo(void) {<br>
              *(pi=(int *)pc, pi) = 42;<br>
          }<br>
          <br>
          The dump of the corresponding CFG looks as follows:<br>
          <br>
           [B2 (ENTRY)]<br>
             Succs (1): B1<br>
          <br>
           [B1]<br>
             1: pi = (int *)pc<br>
             2: pi (ImplicitCastExpr, LValueToRValue, int *)<br>
             3: ... , [B1.2]<br>
             4: *([B1.3]) = 42<br>
             Preds (1): B2<br>
             Succs (1): B0<br>
          <br>
           [B0 (EXIT)]<br>
             Preds (1): B1<br>
          <br>
          The single statement<br>
            *(pi=(int *)pc, pi) = 42;<br>
          is broken up into 4 statements in the CFG.  That means, if I
          iterate over each<br>
          statement of a block like<br>
          <br>
          for (const CFGBlock *block : *CFG) {<br>
            for (const auto &I : *block) {<br>
              if (Optional<CFGStmt> cs = I.getAs<CFGStmt>())<br>
                TF.Visit(cs->getStmt());<br>
            }<br>
          }<br>
          <br>
          and the transfer functions TF recursively visit each
          subexpression, I will<br>
          visit some of them twice.  My plan was actually to construct
          transfer functions<br>
          of type ConstStmtVisitor in order to examine each statement
          recursively.  In<br>
          the past I ran into a similar problem which was related to
          wrongly set<br>
          CFG::BuildOptions.  However, this does not seem to be the case
          this time.<br>
          <br>
          Is it possible to construct a CFG where statements are not
          split?  Or is there<br>
          another approach to walk over all statements of a basic block
          exactly one time?<br>
          <br>
          Cheers,<br>
          Stefan<br>
          _______________________________________________<br>
          cfe-dev mailing list<br>
          <a href="mailto:cfe-dev@lists.llvm.org" target="_blank"
            moz-do-not-send="true">cfe-dev@lists.llvm.org</a><br>
          <a
            href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev"
            rel="noreferrer" target="_blank" moz-do-not-send="true">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
        </blockquote>
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <pre class="moz-quote-pre" wrap="">_______________________________________________
cfe-dev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>
<a class="moz-txt-link-freetext" href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>