1193326Sed//===--- ParentMap.cpp - Mappings from Stmts to their Parents ---*- C++ -*-===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file defines the ParentMap class. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#include "clang/AST/ParentMap.h" 15193326Sed#include "clang/AST/Decl.h" 16193326Sed#include "clang/AST/Expr.h" 17193326Sed#include "llvm/ADT/DenseMap.h" 18193326Sed 19193326Sedusing namespace clang; 20193326Sed 21193326Sedtypedef llvm::DenseMap<Stmt*, Stmt*> MapTy; 22193326Sed 23243830Sdimenum OpaqueValueMode { 24243830Sdim OV_Transparent, 25243830Sdim OV_Opaque 26243830Sdim}; 27243830Sdim 28243830Sdimstatic void BuildParentMap(MapTy& M, Stmt* S, 29243830Sdim OpaqueValueMode OVMode = OV_Transparent) { 30243830Sdim 31243830Sdim switch (S->getStmtClass()) { 32243830Sdim case Stmt::PseudoObjectExprClass: { 33243830Sdim assert(OVMode == OV_Transparent && "Should not appear alongside OVEs"); 34243830Sdim PseudoObjectExpr *POE = cast<PseudoObjectExpr>(S); 35243830Sdim 36243830Sdim M[POE->getSyntacticForm()] = S; 37243830Sdim BuildParentMap(M, POE->getSyntacticForm(), OV_Transparent); 38243830Sdim 39243830Sdim for (PseudoObjectExpr::semantics_iterator I = POE->semantics_begin(), 40243830Sdim E = POE->semantics_end(); 41243830Sdim I != E; ++I) { 42243830Sdim M[*I] = S; 43243830Sdim BuildParentMap(M, *I, OV_Opaque); 44243830Sdim } 45243830Sdim break; 46243830Sdim } 47243830Sdim case Stmt::BinaryConditionalOperatorClass: { 48243830Sdim assert(OVMode == OV_Transparent && "Should not appear alongside OVEs"); 49243830Sdim BinaryConditionalOperator *BCO = cast<BinaryConditionalOperator>(S); 50243830Sdim 51243830Sdim M[BCO->getCommon()] = S; 52243830Sdim BuildParentMap(M, BCO->getCommon(), OV_Transparent); 53243830Sdim 54243830Sdim M[BCO->getCond()] = S; 55243830Sdim BuildParentMap(M, BCO->getCond(), OV_Opaque); 56243830Sdim 57243830Sdim M[BCO->getTrueExpr()] = S; 58243830Sdim BuildParentMap(M, BCO->getTrueExpr(), OV_Opaque); 59243830Sdim 60243830Sdim M[BCO->getFalseExpr()] = S; 61243830Sdim BuildParentMap(M, BCO->getFalseExpr(), OV_Transparent); 62243830Sdim 63243830Sdim break; 64243830Sdim } 65243830Sdim case Stmt::OpaqueValueExprClass: 66243830Sdim if (OVMode == OV_Transparent) { 67243830Sdim OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(S); 68243830Sdim M[OVE->getSourceExpr()] = S; 69243830Sdim BuildParentMap(M, OVE->getSourceExpr(), OV_Transparent); 70243830Sdim } 71243830Sdim break; 72243830Sdim default: 73243830Sdim for (Stmt::child_range I = S->children(); I; ++I) { 74243830Sdim if (*I) { 75243830Sdim M[*I] = S; 76243830Sdim BuildParentMap(M, *I, OVMode); 77239462Sdim } 78193326Sed } 79243830Sdim break; 80239462Sdim } 81193326Sed} 82193326Sed 83193326SedParentMap::ParentMap(Stmt* S) : Impl(0) { 84193326Sed if (S) { 85193326Sed MapTy *M = new MapTy(); 86193326Sed BuildParentMap(*M, S); 87198092Srdivacky Impl = M; 88193326Sed } 89193326Sed} 90193326Sed 91193326SedParentMap::~ParentMap() { 92193326Sed delete (MapTy*) Impl; 93193326Sed} 94193326Sed 95218893Sdimvoid ParentMap::addStmt(Stmt* S) { 96218893Sdim if (S) { 97218893Sdim BuildParentMap(*(MapTy*) Impl, S); 98218893Sdim } 99218893Sdim} 100218893Sdim 101193326SedStmt* ParentMap::getParent(Stmt* S) const { 102193326Sed MapTy* M = (MapTy*) Impl; 103193326Sed MapTy::iterator I = M->find(S); 104193326Sed return I == M->end() ? 0 : I->second; 105193326Sed} 106193326Sed 107193326SedStmt *ParentMap::getParentIgnoreParens(Stmt *S) const { 108193326Sed do { S = getParent(S); } while (S && isa<ParenExpr>(S)); 109193326Sed return S; 110193326Sed} 111193326Sed 112218893SdimStmt *ParentMap::getParentIgnoreParenCasts(Stmt *S) const { 113218893Sdim do { 114218893Sdim S = getParent(S); 115218893Sdim } 116218893Sdim while (S && (isa<ParenExpr>(S) || isa<CastExpr>(S))); 117218893Sdim 118218893Sdim return S; 119218893Sdim} 120218893Sdim 121226633SdimStmt *ParentMap::getParentIgnoreParenImpCasts(Stmt *S) const { 122226633Sdim do { 123226633Sdim S = getParent(S); 124226633Sdim } while (S && isa<Expr>(S) && cast<Expr>(S)->IgnoreParenImpCasts() != S); 125226633Sdim 126226633Sdim return S; 127226633Sdim} 128226633Sdim 129224145SdimStmt *ParentMap::getOuterParenParent(Stmt *S) const { 130224145Sdim Stmt *Paren = 0; 131224145Sdim while (isa<ParenExpr>(S)) { 132224145Sdim Paren = S; 133224145Sdim S = getParent(S); 134224145Sdim }; 135224145Sdim return Paren; 136224145Sdim} 137224145Sdim 138193326Sedbool ParentMap::isConsumedExpr(Expr* E) const { 139193326Sed Stmt *P = getParent(E); 140193326Sed Stmt *DirectChild = E; 141198092Srdivacky 142193326Sed // Ignore parents that are parentheses or casts. 143193326Sed while (P && (isa<ParenExpr>(P) || isa<CastExpr>(P))) { 144193326Sed DirectChild = P; 145193326Sed P = getParent(P); 146193326Sed } 147198092Srdivacky 148193326Sed if (!P) 149193326Sed return false; 150198092Srdivacky 151193326Sed switch (P->getStmtClass()) { 152193326Sed default: 153193326Sed return isa<Expr>(P); 154193326Sed case Stmt::DeclStmtClass: 155193326Sed return true; 156193326Sed case Stmt::BinaryOperatorClass: { 157193326Sed BinaryOperator *BE = cast<BinaryOperator>(P); 158193326Sed // If it is a comma, only the right side is consumed. 159193326Sed // If it isn't a comma, both sides are consumed. 160212904Sdim return BE->getOpcode()!=BO_Comma ||DirectChild==BE->getRHS(); 161193326Sed } 162193326Sed case Stmt::ForStmtClass: 163193326Sed return DirectChild == cast<ForStmt>(P)->getCond(); 164193326Sed case Stmt::WhileStmtClass: 165198092Srdivacky return DirectChild == cast<WhileStmt>(P)->getCond(); 166193326Sed case Stmt::DoStmtClass: 167193326Sed return DirectChild == cast<DoStmt>(P)->getCond(); 168193326Sed case Stmt::IfStmtClass: 169193326Sed return DirectChild == cast<IfStmt>(P)->getCond(); 170193326Sed case Stmt::IndirectGotoStmtClass: 171193326Sed return DirectChild == cast<IndirectGotoStmt>(P)->getTarget(); 172193326Sed case Stmt::SwitchStmtClass: 173193326Sed return DirectChild == cast<SwitchStmt>(P)->getCond(); 174193326Sed case Stmt::ReturnStmtClass: 175193326Sed return true; 176193326Sed } 177193326Sed} 178193326Sed 179