ASTNodeKind ASTNodeKind::getFromNode(const Stmt &S) { switch (S.getStmtClass()) { case Stmt::NoStmtClass: return NKI_None; #define STMT(CLASS, PARENT) \ case Stmt::CLASS##Class: return ASTNodeKind(NKI_##CLASS); #define ABSTRACT_STMT(S) #include "clang/AST/StmtNodes.inc" } llvm_unreachable("invalid stmt kind"); }
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; } }
Stmt * FakeDirectiveHandler::getParent(Stmt * Base) { // Get parent stmt: Stmt * Parent = Base; while((Parent = dyn_cast<clang::Stmt>(PM->getParent(Parent)))) { // Wanted: CompoundStmt, ForStmt, IfStmt, WhileStmt, DoStmt, SwitchStmt // Ignore: CaseStmt, DefaultStmt // Ignore But Don't Expect: BreakStmt, ContinueStmt, NullStmt // Ignore With Big Warnings: Every other stmt switch(Parent->getStmtClass()) { case Stmt::CompoundStmtClass: case Stmt::ForStmtClass: case Stmt::IfStmtClass: case Stmt::WhileStmtClass: case Stmt::DoStmtClass: case Stmt::SwitchStmtClass: return Parent; case Stmt::CaseStmtClass: case Stmt::DefaultStmtClass: case Stmt::ReturnStmtClass: break; case Stmt::BreakStmtClass: case Stmt::ContinueStmtClass: case Stmt::NullStmtClass: default: llvm::errs() << "Warning; Unexpected Parent Stmt Type\n"; } } return NULL; }