Using TreeTransform to copy a function body

Hey All,

I'm trying to use a TreeTransform class to copy the body of an
existing function to a new function, with different arguments. To do
this, I have two FunctionDecls: the original, and the new one with the
modified arguments. I'm then trying to copy the body of the function
with this code:

  // Copy the body of the function, if it exists.
  if(Stmt *body = FD->getBody())
    TreeX inst(*this, FD, fd);
    ContextRAII SavedContext(*this, fd);

and this TreeX class:

// This tree transform checks for any references to the old function's
param decls,
// and changes them to the new function's param decl.
class TreeX : public TreeTransform<TreeX>
  FunctionDecl *from;
  FunctionDecl *to;

  TreeX(Sema &S, FunctionDecl *from, FunctionDecl *to) :
TreeTransform<TreeX>(S), from(from), to(to) { }

  // If E references a param in from, need to change it to param in to.
  ExprResult TransformDeclRefExpr(DeclRefExpr *E)
    ValueDecl *e = E->getDecl();

    for(unsigned int i = 0; i < from->getNumParams(); ++i)
      if(from->getParamDecl(i) == e)
        ParmVarDecl *pd = to->getParamDecl(i);
        return getSema().Owned(DeclRefExpr::Create(
    return E;

This seems to work for nearly trivial functions (i.e. int f(int * x) {
return *x; }), however, if I try to use it on a slightly more complex
function, like this:

int f(int * x)
   int *y = x;
   return *y;

I hit the following assert:

assert(V && "DeclRefExpr not entered in LocalDeclMap?");

In CodeGenFunction::EmitDeclRefLValue.

I can understand why this is, I think the TreeTransform class is not
actually copying the body of the function, but rather both functions
are referencing the same AST elements.

How can I get TreeTransform to truly copy the body of the function,
and associate those new AST elements with the new function? Template
instantiation appears to be heavily built around special template
declarations, which I cannot rely on for my purposes. I also need to
re-run the semantic analysis on the new function, is this possible?


I think there are many people in the audience needing a robust and
generic outliner in Clang for various purpose. So if anyone has one
which is open source, feel free to share. :slight_smile: