[cfe-dev] One thought about llvm::df_iterator

Olaf Krzikalla Olaf.Krzikalla at tu-dresden.de
Mon Jun 15 02:23:18 PDT 2009


Hi @all,

Disclaimer: altough I know this is clang and not llvm, I'm sure there is 
some interest in the topic on this list.

While trying to eleminate as much std::tr1::function as possible I 
stumbled over a design flaw in llvm::df_iterator.
Consider the following code:

void for_all_stmts(Stmt* S, const std::tr1::function<void(Stmt*)>& fn)
{
  if (S)
  {
    fn(S);
    for (Stmt::child_iterator i = S->child_begin(), e = S->child_end(); 
i != e; ++i)
    {
      for_all_stmts(*i, fn);
    }
  }
}

In a first step I want to replace this with:

void for_all_stmts(Stmt* S, const std::tr1::function<void(Stmt*)>& fn)
{
  for (llvm::df_iterator<Stmt*> i = llvm::df_begin(S), e = 
llvm::df_end(S); i != e; ++i)
  {
    if (*i)  fn(*i);
  }
}

However if fn replaces childrens of a just processed statement (which 
happens a lot), the iteration may crash. Looking at df_iterator reveals 
the reason: the first child of a particular statement is stored too 
early for this kind of usage. IMHO this could be fixed by delaying the 
computation of the first child until it's needed (that is in the 
preincrement operator). The only open question would be: how do we mark 
the children iterator invalid before its first use.

Best
Olaf Krzikalla



More information about the cfe-dev mailing list