struct StmtClone : public StmtVisitor { ASTContext& Ctx; std::map m_ClonedStmts; StmtClone(ASTContext& ctx) : Ctx(ctx) {} template T* Clone(T* S) { if (S == NULL) { return NULL; } Stmt* cloned_Stmt = Visit(S); m_ClonedStmts[S] = cloned_Stmt; return static_cast(cloned_Stmt); } Stmt* VisitBinaryOperator(BinaryOperator *Node) { return new (Ctx) BinaryOperator(Clone(Node->getLHS()), Clone(Node->getRHS()), Node->getOpcode(), Node->getType(), Node->getOperatorLoc()); } Stmt* VisitUnaryOperator(UnaryOperator* Node) { return new (Ctx) UnaryOperator(Clone(Node->getSubExpr()), Node->getOpcode(), Node->getType(), Node->getOperatorLoc()); } Stmt* VisitReturnStmt(ReturnStmt *Node) { return new (Ctx) ReturnStmt(Node->getReturnLoc(), Clone(Node->getRetValue())); } Stmt* VisitGotoStmt(GotoStmt *Node) { return new (Ctx) GotoStmt(Node->getLabel(), Node->getGotoLoc(), Node->getLabelLoc()); } Stmt* VisitLabelStmt(LabelStmt *Node) { return new (Ctx) LabelStmt (Node->getIdentLoc(), Node->getID(), Clone(Node->getSubStmt())); } Stmt* VisitCompoundStmt(CompoundStmt *Node) { CompoundStmt* result = new (Ctx) CompoundStmt(Ctx, NULL, 0, Node->getLBracLoc(), Node->getLBracLoc()); unsigned numStmts = Node->size(); if (numStmts > 0) { std::vector clonedBody(numStmts); // have we a stack-based array? std::vector::iterator insertIter = clonedBody.begin(); for (CompoundStmt::const_body_iterator i = Node->body_begin(), e = Node->body_end(); i != e; ++i, ++insertIter) { *insertIter = Clone(*i); } result->setStmts(Ctx, &clonedBody[0], numStmts); } return result; } Stmt* VisitDeclRefExpr(DeclRefExpr* Node) { return new (Ctx) DeclRefExpr(Node->getDecl(), Node->getType(), Node->getLocation(), Node->isTypeDependent(), Node->isValueDependent()); } Stmt* VisitDeclStmt(DeclStmt* Node) { assert(0 && "most important TODO"); return NULL; } Stmt* VisitStmt(Stmt*) { assert(0 && "clone not fully implemented"); return NULL; } };