ParentMap.cpp revision 2de56d1d0c3a504ad1529de2677628bdfbb95cd4
1f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek//===--- ParentMap.cpp - Mappings from Stmts to their Parents ---*- C++ -*-===// 2f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek// 3f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek// The LLVM Compiler Infrastructure 4f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek// 5f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek// This file is distributed under the University of Illinois Open Source 6f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek// License. See LICENSE.TXT for details. 7f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek// 8f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek//===----------------------------------------------------------------------===// 9f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek// 10f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek// This file defines the ParentMap class. 11f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek// 12f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek//===----------------------------------------------------------------------===// 13f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek 14f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek#include "clang/AST/ParentMap.h" 15acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Decl.h" 16f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek#include "clang/AST/Expr.h" 17f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek#include "llvm/ADT/DenseMap.h" 18f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek 19f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenekusing namespace clang; 20f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek 21f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenektypedef llvm::DenseMap<Stmt*, Stmt*> MapTy; 22f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek 23f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenekstatic void BuildParentMap(MapTy& M, Stmt* S) { 24f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I!=E; ++I) 25f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek if (*I) { 26f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek M[*I] = S; 27f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek BuildParentMap(M, *I); 28f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek } 29f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek} 30f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek 31f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed KremenekParentMap::ParentMap(Stmt* S) : Impl(0) { 32f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek if (S) { 33f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek MapTy *M = new MapTy(); 34f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek BuildParentMap(*M, S); 351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Impl = M; 36f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek } 37f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek} 38f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek 39f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed KremenekParentMap::~ParentMap() { 40f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek delete (MapTy*) Impl; 41f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek} 42f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek 43f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed KremenekStmt* ParentMap::getParent(Stmt* S) const { 44f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek MapTy* M = (MapTy*) Impl; 45f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek MapTy::iterator I = M->find(S); 46f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek return I == M->end() ? 0 : I->second; 47f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek} 48b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek 49b1b9f680f5fc65230de877baccae50820a969a94Ted KremenekStmt *ParentMap::getParentIgnoreParens(Stmt *S) const { 50b1b9f680f5fc65230de877baccae50820a969a94Ted Kremenek do { S = getParent(S); } while (S && isa<ParenExpr>(S)); 51b1b9f680f5fc65230de877baccae50820a969a94Ted Kremenek return S; 52b1b9f680f5fc65230de877baccae50820a969a94Ted Kremenek} 53b1b9f680f5fc65230de877baccae50820a969a94Ted Kremenek 54b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenekbool ParentMap::isConsumedExpr(Expr* E) const { 55b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek Stmt *P = getParent(E); 56b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek Stmt *DirectChild = E; 571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 58b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek // Ignore parents that are parentheses or casts. 59ade9ecaba935489840fa74aaf5b4c640d6589e33Ted Kremenek while (P && (isa<ParenExpr>(P) || isa<CastExpr>(P))) { 60b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek DirectChild = P; 61b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek P = getParent(P); 62b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek } 631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 64b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek if (!P) 65b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek return false; 661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 67b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek switch (P->getStmtClass()) { 68b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek default: 69b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek return isa<Expr>(P); 70b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek case Stmt::DeclStmtClass: 71b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek return true; 72b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek case Stmt::BinaryOperatorClass: { 73b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek BinaryOperator *BE = cast<BinaryOperator>(P); 7424ae89a5a25f8971c7436bb3b7663e66ed99b987Ted Kremenek // If it is a comma, only the right side is consumed. 75e42ac98bc2d50506216b6ef258594bdaa59c47c1Ted Kremenek // If it isn't a comma, both sides are consumed. 762de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall return BE->getOpcode()!=BO_Comma ||DirectChild==BE->getRHS(); 77b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek } 78b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek case Stmt::ForStmtClass: 79b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek return DirectChild == cast<ForStmt>(P)->getCond(); 80b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek case Stmt::WhileStmtClass: 811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return DirectChild == cast<WhileStmt>(P)->getCond(); 82b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek case Stmt::DoStmtClass: 83b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek return DirectChild == cast<DoStmt>(P)->getCond(); 84b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek case Stmt::IfStmtClass: 85b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek return DirectChild == cast<IfStmt>(P)->getCond(); 86b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek case Stmt::IndirectGotoStmtClass: 87b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek return DirectChild == cast<IndirectGotoStmt>(P)->getTarget(); 88b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek case Stmt::SwitchStmtClass: 89b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek return DirectChild == cast<SwitchStmt>(P)->getCond(); 90b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek case Stmt::ReturnStmtClass: 91b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek return true; 92b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek } 93b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek} 94b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek 95