ASTNodeInfo EvaluateTSynthesizer::VisitBinaryOperator(BinaryOperator* Node) { ASTNodeInfo rhs = Visit(Node->getRHS()); ASTNodeInfo lhs; lhs = Visit(Node->getLHS()); assert((lhs.hasSingleNode() || rhs.hasSingleNode()) && "1:N replacements are not implemented yet!"); // Try find out the type of the left-hand-side of the operator // and give the hint to the right-hand-side in order to replace the // dependent symbol if (Node->isAssignmentOp() && rhs.isForReplacement() && !lhs.isForReplacement()) { if (Expr* LHSExpr = lhs.getAs<Expr>()) if (!IsArtificiallyDependent(LHSExpr)) { const QualType LHSTy = LHSExpr->getType(); Node->setRHS(SubstituteUnknownSymbol(LHSTy, rhs.castTo<Expr>())); Node->setTypeDependent(false); Node->setValueDependent(false); return ASTNodeInfo(Node, /*needs eval*/false); } } return ASTNodeInfo(Node, IsArtificiallyDependent(Node)); }
ASTNodeInfo EvaluateTSynthesizer::VisitCompoundStmt(CompoundStmt* Node) { ++m_NestedCompoundStmts; ASTNodes Children; ASTNodes NewChildren; if (GetChildren(Children, Node)) { ASTNodes::iterator it; for (it = Children.begin(); it != Children.end(); ++it) { ASTNodeInfo NewNode = Visit(*it); if (!NewNode.hasSingleNode()) { ASTNodes& NewStmts(NewNode.getNodes()); for(unsigned i = 0; i < NewStmts.size(); ++i) NewChildren.push_back(NewStmts[i]); Node->setStmts(*m_Context, NewChildren.data(), NewChildren.size()); // Resolve all 1:n replacements Visit(Node); } else { if (NewNode.isForReplacement()) { if (Expr* E = NewNode.getAs<Expr>()) { // Check whether value printer has been requested bool valuePrinterReq = false; // If this was the last or the last is not null stmt, means that // we need to value print. // If this is in a wrapper function's body then look for VP. if (FunctionDecl* FD = dyn_cast<FunctionDecl>(m_CurDeclContext)) valuePrinterReq = m_NestedCompoundStmts < 2 && utils::Analyze::IsWrapper(FD) && ((it+1) == Children.end() || ((it+2) == Children.end() && !isa<NullStmt>(*(it+1)))); // Assume void if still not escaped NewChildren.push_back(SubstituteUnknownSymbol(m_Context->VoidTy,E, valuePrinterReq)); } } else NewChildren.push_back(*it); } } } Node->setStmts(*m_Context, NewChildren.data(), NewChildren.size()); --m_NestedCompoundStmts; return ASTNodeInfo(Node, 0); }
ASTNodeInfo EvaluateTSynthesizer::VisitExpr(Expr* Node) { for (Stmt::child_iterator I = Node->child_begin(), E = Node->child_end(); I != E; ++I) { if (*I) { ASTNodeInfo NewNode = Visit(*I); assert(NewNode.hasSingleNode() && "Cannot have more than one stmt at that point"); if (NewNode.isForReplacement()) { if (Expr *E = NewNode.getAs<Expr>()) // Assume void if still not escaped *I = SubstituteUnknownSymbol(m_Context->VoidTy, E); } else { *I = NewNode.getAsSingleNode(); } } } return ASTNodeInfo(Node, 0); }
ASTNodeInfo EvaluateTSynthesizer::VisitCompoundStmt(CompoundStmt* Node) { ASTNodes Children; ASTNodes NewChildren; if (GetChildren(Children, Node)) { ASTNodes::iterator it; for (it = Children.begin(); it != Children.end(); ++it) { ASTNodeInfo NewNode = Visit(*it); if (!NewNode.hasSingleNode()) { ASTNodes& NewStmts(NewNode.getNodes()); for(unsigned i = 0; i < NewStmts.size(); ++i) NewChildren.push_back(NewStmts[i]); Node->setStmts(*m_Context, NewChildren.data(), NewChildren.size()); // Resolve all 1:n replacements Visit(Node); } else { if (NewNode.isForReplacement()) { if (Expr* E = NewNode.getAs<Expr>()) { // Check whether value printer has been requested bool valuePrinterReq = false; if ((it+1) == Children.end() || !isa<NullStmt>(*(it+1))) valuePrinterReq = true; // Assume void if still not escaped NewChildren.push_back(SubstituteUnknownSymbol(m_Context->VoidTy,E, valuePrinterReq)); } } else NewChildren.push_back(*it); } } } Node->setStmts(*m_Context, NewChildren.data(), NewChildren.size()); return ASTNodeInfo(Node, 0); }