ParentMap.cpp revision 2b1b025fa6e848ec36c0554924d7d63342aa80e4
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) { 247502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall for (Stmt::child_range I = S->children(); I; ++I) 25f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek if (*I) { 262b1b025fa6e848ec36c0554924d7d63342aa80e4Jordan Rose // Prefer the first time we see this statement in the traversal. 272b1b025fa6e848ec36c0554924d7d63342aa80e4Jordan Rose // This is important for PseudoObjectExprs. 282b1b025fa6e848ec36c0554924d7d63342aa80e4Jordan Rose Stmt *&Parent = M[*I]; 292b1b025fa6e848ec36c0554924d7d63342aa80e4Jordan Rose if (!Parent) { 302b1b025fa6e848ec36c0554924d7d63342aa80e4Jordan Rose Parent = S; 312b1b025fa6e848ec36c0554924d7d63342aa80e4Jordan Rose BuildParentMap(M, *I); 322b1b025fa6e848ec36c0554924d7d63342aa80e4Jordan Rose } 33f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek } 34e215ba1c2a3f29fe2cbc4cfb0e532cd204970c49Ted Kremenek 35e215ba1c2a3f29fe2cbc4cfb0e532cd204970c49Ted Kremenek // Also include the source expr tree of an OpaqueValueExpr in the map. 362b1b025fa6e848ec36c0554924d7d63342aa80e4Jordan Rose if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(S)) { 372b1b025fa6e848ec36c0554924d7d63342aa80e4Jordan Rose M[OVE->getSourceExpr()] = S; 38e215ba1c2a3f29fe2cbc4cfb0e532cd204970c49Ted Kremenek BuildParentMap(M, OVE->getSourceExpr()); 392b1b025fa6e848ec36c0554924d7d63342aa80e4Jordan Rose } 40f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek} 41f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek 42f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed KremenekParentMap::ParentMap(Stmt* S) : Impl(0) { 43f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek if (S) { 44f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek MapTy *M = new MapTy(); 45f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek BuildParentMap(*M, S); 461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Impl = M; 47f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek } 48f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek} 49f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek 50f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed KremenekParentMap::~ParentMap() { 51f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek delete (MapTy*) Impl; 52f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek} 53f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek 54d6543f8bbac18cdb678a67da2a676c30c2941ecaTed Kremenekvoid ParentMap::addStmt(Stmt* S) { 55d6543f8bbac18cdb678a67da2a676c30c2941ecaTed Kremenek if (S) { 56d6543f8bbac18cdb678a67da2a676c30c2941ecaTed Kremenek BuildParentMap(*(MapTy*) Impl, S); 57d6543f8bbac18cdb678a67da2a676c30c2941ecaTed Kremenek } 58d6543f8bbac18cdb678a67da2a676c30c2941ecaTed Kremenek} 59d6543f8bbac18cdb678a67da2a676c30c2941ecaTed Kremenek 60f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed KremenekStmt* ParentMap::getParent(Stmt* S) const { 61f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek MapTy* M = (MapTy*) Impl; 62f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek MapTy::iterator I = M->find(S); 63f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek return I == M->end() ? 0 : I->second; 64f8e32cf062f39fff1a00aff748cb6b5dc0abc2feTed Kremenek} 65b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek 66b1b9f680f5fc65230de877baccae50820a969a94Ted KremenekStmt *ParentMap::getParentIgnoreParens(Stmt *S) const { 67b1b9f680f5fc65230de877baccae50820a969a94Ted Kremenek do { S = getParent(S); } while (S && isa<ParenExpr>(S)); 68b1b9f680f5fc65230de877baccae50820a969a94Ted Kremenek return S; 69b1b9f680f5fc65230de877baccae50820a969a94Ted Kremenek} 70b1b9f680f5fc65230de877baccae50820a969a94Ted Kremenek 71f4e532b5a1683a9f6c842f361c7415bf3474315fTed KremenekStmt *ParentMap::getParentIgnoreParenCasts(Stmt *S) const { 72f4e532b5a1683a9f6c842f361c7415bf3474315fTed Kremenek do { 73f4e532b5a1683a9f6c842f361c7415bf3474315fTed Kremenek S = getParent(S); 74f4e532b5a1683a9f6c842f361c7415bf3474315fTed Kremenek } 75f4e532b5a1683a9f6c842f361c7415bf3474315fTed Kremenek while (S && (isa<ParenExpr>(S) || isa<CastExpr>(S))); 76f4e532b5a1683a9f6c842f361c7415bf3474315fTed Kremenek 77f4e532b5a1683a9f6c842f361c7415bf3474315fTed Kremenek return S; 78f4e532b5a1683a9f6c842f361c7415bf3474315fTed Kremenek} 79f4e532b5a1683a9f6c842f361c7415bf3474315fTed Kremenek 8018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios KyrtzidisStmt *ParentMap::getParentIgnoreParenImpCasts(Stmt *S) const { 8118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis do { 8218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis S = getParent(S); 8318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } while (S && isa<Expr>(S) && cast<Expr>(S)->IgnoreParenImpCasts() != S); 8418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 8518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return S; 8618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis} 8718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 88f85e193739c953358c865005855253af4f68a497John McCallStmt *ParentMap::getOuterParenParent(Stmt *S) const { 89f85e193739c953358c865005855253af4f68a497John McCall Stmt *Paren = 0; 90f85e193739c953358c865005855253af4f68a497John McCall while (isa<ParenExpr>(S)) { 91f85e193739c953358c865005855253af4f68a497John McCall Paren = S; 92f85e193739c953358c865005855253af4f68a497John McCall S = getParent(S); 93f85e193739c953358c865005855253af4f68a497John McCall }; 94f85e193739c953358c865005855253af4f68a497John McCall return Paren; 95f85e193739c953358c865005855253af4f68a497John McCall} 96f85e193739c953358c865005855253af4f68a497John McCall 97b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenekbool ParentMap::isConsumedExpr(Expr* E) const { 98b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek Stmt *P = getParent(E); 99b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek Stmt *DirectChild = E; 1001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 101b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek // Ignore parents that are parentheses or casts. 102ade9ecaba935489840fa74aaf5b4c640d6589e33Ted Kremenek while (P && (isa<ParenExpr>(P) || isa<CastExpr>(P))) { 103b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek DirectChild = P; 104b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek P = getParent(P); 105b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek } 1061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 107b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek if (!P) 108b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek return false; 1091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 110b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek switch (P->getStmtClass()) { 111b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek default: 112b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek return isa<Expr>(P); 113b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek case Stmt::DeclStmtClass: 114b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek return true; 115b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek case Stmt::BinaryOperatorClass: { 116b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek BinaryOperator *BE = cast<BinaryOperator>(P); 11724ae89a5a25f8971c7436bb3b7663e66ed99b987Ted Kremenek // If it is a comma, only the right side is consumed. 118e42ac98bc2d50506216b6ef258594bdaa59c47c1Ted Kremenek // If it isn't a comma, both sides are consumed. 1192de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall return BE->getOpcode()!=BO_Comma ||DirectChild==BE->getRHS(); 120b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek } 121b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek case Stmt::ForStmtClass: 122b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek return DirectChild == cast<ForStmt>(P)->getCond(); 123b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek case Stmt::WhileStmtClass: 1241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return DirectChild == cast<WhileStmt>(P)->getCond(); 125b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek case Stmt::DoStmtClass: 126b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek return DirectChild == cast<DoStmt>(P)->getCond(); 127b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek case Stmt::IfStmtClass: 128b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek return DirectChild == cast<IfStmt>(P)->getCond(); 129b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek case Stmt::IndirectGotoStmtClass: 130b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek return DirectChild == cast<IndirectGotoStmt>(P)->getTarget(); 131b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek case Stmt::SwitchStmtClass: 132b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek return DirectChild == cast<SwitchStmt>(P)->getCond(); 133b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek case Stmt::ReturnStmtClass: 134b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek return true; 135b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek } 136b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek} 137b930d7adb7cb7642c9c49b39df04ebd5cbfa713aTed Kremenek 138