ScopeInfo.cpp revision f1c1ba089cd8930c1193fcd20fb38cab834a8f94
1a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose//===--- ScopeInfo.cpp - Information about a semantic context -------------===// 2a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// 3a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// The LLVM Compiler Infrastructure 4a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// 5a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// This file is distributed under the University of Illinois Open Source 6a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// License. See LICENSE.TXT for details. 7a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// 8a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose//===----------------------------------------------------------------------===// 9a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// 10a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// This file implements FunctionScopeInfo and its subclasses, which contain 11a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// information about a single function, block, lambda, or method body. 12a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// 13a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose//===----------------------------------------------------------------------===// 14a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 15a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose#include "clang/Sema/ScopeInfo.h" 16a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose#include "clang/AST/Decl.h" 17a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose#include "clang/AST/DeclObjC.h" 18a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose#include "clang/AST/Expr.h" 19a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose#include "clang/AST/ExprCXX.h" 20a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose#include "clang/AST/ExprObjC.h" 21a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 22a55d32d1b8f799bf58c02540983976368c42d895Jordan Roseusing namespace clang; 23a55d32d1b8f799bf58c02540983976368c42d895Jordan Roseusing namespace sema; 24a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 25a55d32d1b8f799bf58c02540983976368c42d895Jordan Rosevoid FunctionScopeInfo::Clear() { 26a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose HasBranchProtectedScope = false; 27a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose HasBranchIntoScope = false; 28a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose HasIndirectGoto = false; 29a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 30a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose SwitchStack.clear(); 31a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose Returns.clear(); 32a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose ErrorTrap.reset(); 33a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose PossiblyUnreachableDiags.clear(); 34a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose WeakObjectUses.clear(); 35a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose} 36a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 37a55d32d1b8f799bf58c02540983976368c42d895Jordan Rosestatic const NamedDecl *getBestPropertyDecl(const ObjCPropertyRefExpr *PropE) { 38a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (PropE->isExplicitProperty()) 39a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose return PropE->getExplicitProperty(); 40a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 41a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose return PropE->getImplicitPropertyGetter(); 42a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose} 43a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 44a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseFunctionScopeInfo::WeakObjectProfileTy::BaseInfoTy 45a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseFunctionScopeInfo::WeakObjectProfileTy::getBaseInfo(const Expr *E) { 46a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose E = E->IgnoreParenCasts(); 47a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 48a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const NamedDecl *D = 0; 49a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose bool IsExact = false; 50a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 51a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose switch (E->getStmtClass()) { 52a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose case Stmt::DeclRefExprClass: 53a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose D = cast<DeclRefExpr>(E)->getDecl(); 54a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose IsExact = isa<VarDecl>(D); 55a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose break; 56a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose case Stmt::MemberExprClass: { 57a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const MemberExpr *ME = cast<MemberExpr>(E); 58a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose D = ME->getMemberDecl(); 59a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose IsExact = isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()); 60a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose break; 61a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } 62a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose case Stmt::ObjCIvarRefExprClass: { 63a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const ObjCIvarRefExpr *IE = cast<ObjCIvarRefExpr>(E); 64a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose D = IE->getDecl(); 65bbff82f302a1dd67589f65912351978905f0c5a7Anna Zaks IsExact = IE->getBase()->isObjCSelfExpr(); 66a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose break; 67a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } 68a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose case Stmt::PseudoObjectExprClass: { 69a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const PseudoObjectExpr *POE = cast<PseudoObjectExpr>(E); 70a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const ObjCPropertyRefExpr *BaseProp = 71a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm()); 72a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (BaseProp) { 73a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose D = getBestPropertyDecl(BaseProp); 74a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 75a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const Expr *DoubleBase = BaseProp->getBase(); 76a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(DoubleBase)) 77a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose DoubleBase = OVE->getSourceExpr(); 78a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 79bbff82f302a1dd67589f65912351978905f0c5a7Anna Zaks IsExact = DoubleBase->isObjCSelfExpr(); 80a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } 81a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose break; 82a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } 83a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose default: 84a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose break; 85a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } 86a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 87a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose return BaseInfoTy(D, IsExact); 88a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose} 89a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 90a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 91a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy( 92a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const ObjCPropertyRefExpr *PropE) 93a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose : Base(0, true), Property(getBestPropertyDecl(PropE)) { 94a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 95a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (PropE->isObjectReceiver()) { 96a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(PropE->getBase()); 97a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const Expr *E = OVE->getSourceExpr(); 98a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose Base = getBaseInfo(E); 99a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } else if (PropE->isClassReceiver()) { 100a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose Base.setPointer(PropE->getClassReceiver()); 101a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } else { 102a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose assert(PropE->isSuperReceiver()); 103a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } 104a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose} 105a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 1067fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan RoseFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(const Expr *BaseE, 1077fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose const ObjCPropertyDecl *Prop) 1087fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose : Base(0, true), Property(Prop) { 1097fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose if (BaseE) 1107fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose Base = getBaseInfo(BaseE); 1117fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose // else, this is a message accessing a property on super. 1127fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose} 1137fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose 114a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy( 115a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const DeclRefExpr *DRE) 116a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose : Base(0, true), Property(DRE->getDecl()) { 117a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose assert(isa<VarDecl>(Property)); 118a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose} 119a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 120a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy( 121a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const ObjCIvarRefExpr *IvarE) 122a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose : Base(getBaseInfo(IvarE->getBase())), Property(IvarE->getDecl()) { 123a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose} 124a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 1257fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rosevoid FunctionScopeInfo::recordUseOfWeak(const ObjCMessageExpr *Msg, 1267fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose const ObjCPropertyDecl *Prop) { 1277fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose assert(Msg && Prop); 1287fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose WeakUseVector &Uses = 1297fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose WeakObjectUses[WeakObjectProfileTy(Msg->getInstanceReceiver(), Prop)]; 1307fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose Uses.push_back(WeakUseTy(Msg, Msg->getNumArgs() == 0)); 1317fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose} 1327fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose 133a55d32d1b8f799bf58c02540983976368c42d895Jordan Rosevoid FunctionScopeInfo::markSafeWeakUse(const Expr *E) { 134c88f8ef9d85a537233b4423d31dbf8bc81be525aJordan Rose E = E->IgnoreParenCasts(); 135a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 136a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) { 137a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose markSafeWeakUse(POE->getSyntacticForm()); 138a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose return; 139a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } 140a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 141a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (const ConditionalOperator *Cond = dyn_cast<ConditionalOperator>(E)) { 142a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose markSafeWeakUse(Cond->getTrueExpr()); 143a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose markSafeWeakUse(Cond->getFalseExpr()); 144a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose return; 145a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } 146a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 147a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (const BinaryConditionalOperator *Cond = 148a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose dyn_cast<BinaryConditionalOperator>(E)) { 149a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose markSafeWeakUse(Cond->getCommon()); 150a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose markSafeWeakUse(Cond->getFalseExpr()); 151a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose return; 152a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } 153a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 154a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose // Has this weak object been seen before? 155a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose FunctionScopeInfo::WeakObjectUseMap::iterator Uses; 156a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) 1577fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr)); 158a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E)) 1597fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE)); 160a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) 1617fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE)); 162f1c1ba089cd8930c1193fcd20fb38cab834a8f94Jordan Rose else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) { 1637fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose Uses = WeakObjectUses.end(); 1647fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose if (const ObjCMethodDecl *MD = MsgE->getMethodDecl()) { 1657fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose if (const ObjCPropertyDecl *Prop = MD->findPropertyDecl()) { 1667fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose Uses = 1677fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose WeakObjectUses.find(WeakObjectProfileTy(MsgE->getInstanceReceiver(), 1687fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose Prop)); 1697fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose } 1707fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose } 1717fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose } 172a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose else 173a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose return; 174a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 175a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (Uses == WeakObjectUses.end()) 176a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose return; 177a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 178a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose // Has there been a read from the object using this Expr? 179a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose FunctionScopeInfo::WeakUseVector::reverse_iterator ThisUse = 180a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose std::find(Uses->second.rbegin(), Uses->second.rend(), WeakUseTy(E, true)); 181a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (ThisUse == Uses->second.rend()) 182a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose return; 183a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 184a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose ThisUse->markSafe(); 185a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose} 186a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 187a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseFunctionScopeInfo::~FunctionScopeInfo() { } 188a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseBlockScopeInfo::~BlockScopeInfo() { } 189a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseLambdaScopeInfo::~LambdaScopeInfo() { } 190