1 //===--- ParentMap.cpp - Mappings from Stmts to their Parents ---*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the ParentMap class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/AST/ParentMap.h" 15 #include "clang/AST/Decl.h" 16 #include "clang/AST/Expr.h" 17 #include "llvm/ADT/DenseMap.h" 18 19 using namespace clang; 20 21 typedef llvm::DenseMap<Stmt*, Stmt*> MapTy; 22 23 static void BuildParentMap(MapTy& M, Stmt* S) { 24 for (Stmt::child_range I = S->children(); I; ++I) 25 if (*I) { 26 M[*I] = S; 27 BuildParentMap(M, *I); 28 } 29 } 30 31 ParentMap::ParentMap(Stmt* S) : Impl(0) { 32 if (S) { 33 MapTy *M = new MapTy(); 34 BuildParentMap(*M, S); 35 Impl = M; 36 } 37 } 38 39 ParentMap::~ParentMap() { 40 delete (MapTy*) Impl; 41 } 42 43 void ParentMap::addStmt(Stmt* S) { 44 if (S) { 45 BuildParentMap(*(MapTy*) Impl, S); 46 } 47 } 48 49 Stmt* ParentMap::getParent(Stmt* S) const { 50 MapTy* M = (MapTy*) Impl; 51 MapTy::iterator I = M->find(S); 52 return I == M->end() ? 0 : I->second; 53 } 54 55 Stmt *ParentMap::getParentIgnoreParens(Stmt *S) const { 56 do { S = getParent(S); } while (S && isa<ParenExpr>(S)); 57 return S; 58 } 59 60 Stmt *ParentMap::getParentIgnoreParenCasts(Stmt *S) const { 61 do { 62 S = getParent(S); 63 } 64 while (S && (isa<ParenExpr>(S) || isa<CastExpr>(S))); 65 66 return S; 67 } 68 69 Stmt *ParentMap::getOuterParenParent(Stmt *S) const { 70 Stmt *Paren = 0; 71 while (isa<ParenExpr>(S)) { 72 Paren = S; 73 S = getParent(S); 74 }; 75 return Paren; 76 } 77 78 bool ParentMap::isConsumedExpr(Expr* E) const { 79 Stmt *P = getParent(E); 80 Stmt *DirectChild = E; 81 82 // Ignore parents that are parentheses or casts. 83 while (P && (isa<ParenExpr>(P) || isa<CastExpr>(P))) { 84 DirectChild = P; 85 P = getParent(P); 86 } 87 88 if (!P) 89 return false; 90 91 switch (P->getStmtClass()) { 92 default: 93 return isa<Expr>(P); 94 case Stmt::DeclStmtClass: 95 return true; 96 case Stmt::BinaryOperatorClass: { 97 BinaryOperator *BE = cast<BinaryOperator>(P); 98 // If it is a comma, only the right side is consumed. 99 // If it isn't a comma, both sides are consumed. 100 return BE->getOpcode()!=BO_Comma ||DirectChild==BE->getRHS(); 101 } 102 case Stmt::ForStmtClass: 103 return DirectChild == cast<ForStmt>(P)->getCond(); 104 case Stmt::WhileStmtClass: 105 return DirectChild == cast<WhileStmt>(P)->getCond(); 106 case Stmt::DoStmtClass: 107 return DirectChild == cast<DoStmt>(P)->getCond(); 108 case Stmt::IfStmtClass: 109 return DirectChild == cast<IfStmt>(P)->getCond(); 110 case Stmt::IndirectGotoStmtClass: 111 return DirectChild == cast<IndirectGotoStmt>(P)->getTarget(); 112 case Stmt::SwitchStmtClass: 113 return DirectChild == cast<SwitchStmt>(P)->getCond(); 114 case Stmt::ReturnStmtClass: 115 return true; 116 } 117 } 118 119