bool ReserveCandidates::expressionIsComplex(clang::Expr *expr) const { if (!expr) return false; vector<CallExpr*> callExprs; HierarchyUtils::getChilds<CallExpr>(expr, callExprs); for (CallExpr *callExpr : callExprs) { if (QtUtils::isJavaIterator(dyn_cast<CXXMemberCallExpr>(callExpr))) continue; QualType qt = callExpr->getType(); const Type *t = qt.getTypePtrOrNull(); if (t && (!t->isIntegerType() || t->isBooleanType())) return true; } vector<ArraySubscriptExpr*> subscriptExprs; HierarchyUtils::getChilds<ArraySubscriptExpr>(expr, subscriptExprs); if (!subscriptExprs.empty()) return true; BinaryOperator* binary = dyn_cast<BinaryOperator>(expr); if (binary && binary->isAssignmentOp()) { // Filter things like for ( ...; ...; next = node->next) Expr *rhs = binary->getRHS(); if (isa<MemberExpr>(rhs) || (isa<ImplicitCastExpr>(rhs) && dyn_cast_or_null<MemberExpr>(HierarchyUtils::getFirstChildAtDepth(rhs, 1)))) return true; } // llvm::errs() << expr->getStmtClassName() << "\n"; return false; }
bool ParentMap::isConsumedExpr(Expr* E) const { Stmt *P = getParent(E); Stmt *DirectChild = E; // Ignore parents that don't guarantee consumption. while (P && (isa<ParenExpr>(P) || isa<CastExpr>(P) || isa<ExprWithCleanups>(P))) { DirectChild = P; P = getParent(P); } if (!P) return false; switch (P->getStmtClass()) { default: return isa<Expr>(P); case Stmt::DeclStmtClass: return true; case Stmt::BinaryOperatorClass: { BinaryOperator *BE = cast<BinaryOperator>(P); // If it is a comma, only the right side is consumed. // If it isn't a comma, both sides are consumed. return BE->getOpcode()!=BO_Comma ||DirectChild==BE->getRHS(); } case Stmt::ForStmtClass: return DirectChild == cast<ForStmt>(P)->getCond(); case Stmt::WhileStmtClass: return DirectChild == cast<WhileStmt>(P)->getCond(); case Stmt::DoStmtClass: return DirectChild == cast<DoStmt>(P)->getCond(); case Stmt::IfStmtClass: return DirectChild == cast<IfStmt>(P)->getCond(); case Stmt::IndirectGotoStmtClass: return DirectChild == cast<IndirectGotoStmt>(P)->getTarget(); case Stmt::SwitchStmtClass: return DirectChild == cast<SwitchStmt>(P)->getCond(); case Stmt::ObjCForCollectionStmtClass: return DirectChild == cast<ObjCForCollectionStmt>(P)->getCollection(); case Stmt::ReturnStmtClass: return true; } }
string NetworkDriverRewriteVisitor::GetSharedStructStrInFunctionBody(Stmt *body, bool doLog) { string shared_struct_str = ""; for (auto i = body->child_begin(), e = body->child_end(); i != e; ++i) { if (isa<DeclStmt>(*i)) { DeclStmt *declStmt = cast<DeclStmt>(*i); if (!declStmt->isSingleDecl() && !isa<VarDecl>(declStmt->getSingleDecl())) continue; VarDecl *varDecl = cast<VarDecl>(declStmt->getSingleDecl()); if (!isa<ValueDecl>(varDecl)) continue; ValueDecl *value = cast<ValueDecl>(varDecl); if (value->getType().getAsString(Context->getPrintingPolicy()) != "struct net_device *") continue; if (!isa<NamedDecl>(varDecl)) continue; if (varDecl->getInit() == 0 || !isa<CallExpr>(varDecl->getInit())) continue; CallExpr *callExpr = cast<CallExpr>(varDecl->getInit()); shared_struct_str = GetSharedStructStr(callExpr); if (shared_struct_str != "") { if (doLog) { Expr *callee = callExpr->getCallee(); ImplicitCastExpr *calleeImplExpr = cast<ImplicitCastExpr>(callee); DeclRefExpr *calleeDeclExpr = cast<DeclRefExpr>(calleeImplExpr->getSubExpr()); DI->getInstance().AddSharedStructInformation("whoop_network_shared_struct", calleeDeclExpr->getNameInfo().getAsString()); } break; } } else if (isa<BinaryOperator>(*i)) { BinaryOperator *binOp = cast<BinaryOperator>(*i); if (!isa<CallExpr>(binOp->getRHS())) continue; CallExpr *callExpr = cast<CallExpr>(binOp->getRHS()); shared_struct_str = GetSharedStructStr(callExpr); if (shared_struct_str != "") { if (doLog) { Expr *callee = callExpr->getCallee(); ImplicitCastExpr *calleeImplExpr = cast<ImplicitCastExpr>(callee); DeclRefExpr *calleeDeclExpr = cast<DeclRefExpr>(calleeImplExpr->getSubExpr()); DI->getInstance().AddSharedStructInformation("whoop_network_shared_struct", calleeDeclExpr->getNameInfo().getAsString()); } break; } } } return shared_struct_str; }
bool isRemainderWhenDevidingByTwo(Expr *expr) { BinaryOperator *binaryOperator = dyn_cast<BinaryOperator>(expr); return binaryOperator && binaryOperator->getOpcode() == BO_Rem && isIntegerLiteral(binaryOperator->getRHS(), 2); }