1*f4a2713aSLionel Sambuc //===--- ScopeInfo.cpp - Information about a semantic context -------------===// 2*f4a2713aSLionel Sambuc // 3*f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure 4*f4a2713aSLionel Sambuc // 5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details. 7*f4a2713aSLionel Sambuc // 8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 9*f4a2713aSLionel Sambuc // 10*f4a2713aSLionel Sambuc // This file implements FunctionScopeInfo and its subclasses, which contain 11*f4a2713aSLionel Sambuc // information about a single function, block, lambda, or method body. 12*f4a2713aSLionel Sambuc // 13*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 14*f4a2713aSLionel Sambuc 15*f4a2713aSLionel Sambuc #include "clang/Sema/ScopeInfo.h" 16*f4a2713aSLionel Sambuc #include "clang/AST/Decl.h" 17*f4a2713aSLionel Sambuc #include "clang/AST/DeclObjC.h" 18*f4a2713aSLionel Sambuc #include "clang/AST/Expr.h" 19*f4a2713aSLionel Sambuc #include "clang/AST/ExprCXX.h" 20*f4a2713aSLionel Sambuc #include "clang/AST/ExprObjC.h" 21*f4a2713aSLionel Sambuc 22*f4a2713aSLionel Sambuc using namespace clang; 23*f4a2713aSLionel Sambuc using namespace sema; 24*f4a2713aSLionel Sambuc 25*f4a2713aSLionel Sambuc void FunctionScopeInfo::Clear() { 26*f4a2713aSLionel Sambuc HasBranchProtectedScope = false; 27*f4a2713aSLionel Sambuc HasBranchIntoScope = false; 28*f4a2713aSLionel Sambuc HasIndirectGoto = false; 29*f4a2713aSLionel Sambuc 30*f4a2713aSLionel Sambuc SwitchStack.clear(); 31*f4a2713aSLionel Sambuc Returns.clear(); 32*f4a2713aSLionel Sambuc ErrorTrap.reset(); 33*f4a2713aSLionel Sambuc PossiblyUnreachableDiags.clear(); 34*f4a2713aSLionel Sambuc WeakObjectUses.clear(); 35*f4a2713aSLionel Sambuc } 36*f4a2713aSLionel Sambuc 37*f4a2713aSLionel Sambuc static const NamedDecl *getBestPropertyDecl(const ObjCPropertyRefExpr *PropE) { 38*f4a2713aSLionel Sambuc if (PropE->isExplicitProperty()) 39*f4a2713aSLionel Sambuc return PropE->getExplicitProperty(); 40*f4a2713aSLionel Sambuc 41*f4a2713aSLionel Sambuc return PropE->getImplicitPropertyGetter(); 42*f4a2713aSLionel Sambuc } 43*f4a2713aSLionel Sambuc 44*f4a2713aSLionel Sambuc FunctionScopeInfo::WeakObjectProfileTy::BaseInfoTy 45*f4a2713aSLionel Sambuc FunctionScopeInfo::WeakObjectProfileTy::getBaseInfo(const Expr *E) { 46*f4a2713aSLionel Sambuc E = E->IgnoreParenCasts(); 47*f4a2713aSLionel Sambuc 48*f4a2713aSLionel Sambuc const NamedDecl *D = 0; 49*f4a2713aSLionel Sambuc bool IsExact = false; 50*f4a2713aSLionel Sambuc 51*f4a2713aSLionel Sambuc switch (E->getStmtClass()) { 52*f4a2713aSLionel Sambuc case Stmt::DeclRefExprClass: 53*f4a2713aSLionel Sambuc D = cast<DeclRefExpr>(E)->getDecl(); 54*f4a2713aSLionel Sambuc IsExact = isa<VarDecl>(D); 55*f4a2713aSLionel Sambuc break; 56*f4a2713aSLionel Sambuc case Stmt::MemberExprClass: { 57*f4a2713aSLionel Sambuc const MemberExpr *ME = cast<MemberExpr>(E); 58*f4a2713aSLionel Sambuc D = ME->getMemberDecl(); 59*f4a2713aSLionel Sambuc IsExact = isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()); 60*f4a2713aSLionel Sambuc break; 61*f4a2713aSLionel Sambuc } 62*f4a2713aSLionel Sambuc case Stmt::ObjCIvarRefExprClass: { 63*f4a2713aSLionel Sambuc const ObjCIvarRefExpr *IE = cast<ObjCIvarRefExpr>(E); 64*f4a2713aSLionel Sambuc D = IE->getDecl(); 65*f4a2713aSLionel Sambuc IsExact = IE->getBase()->isObjCSelfExpr(); 66*f4a2713aSLionel Sambuc break; 67*f4a2713aSLionel Sambuc } 68*f4a2713aSLionel Sambuc case Stmt::PseudoObjectExprClass: { 69*f4a2713aSLionel Sambuc const PseudoObjectExpr *POE = cast<PseudoObjectExpr>(E); 70*f4a2713aSLionel Sambuc const ObjCPropertyRefExpr *BaseProp = 71*f4a2713aSLionel Sambuc dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm()); 72*f4a2713aSLionel Sambuc if (BaseProp) { 73*f4a2713aSLionel Sambuc D = getBestPropertyDecl(BaseProp); 74*f4a2713aSLionel Sambuc 75*f4a2713aSLionel Sambuc const Expr *DoubleBase = BaseProp->getBase(); 76*f4a2713aSLionel Sambuc if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(DoubleBase)) 77*f4a2713aSLionel Sambuc DoubleBase = OVE->getSourceExpr(); 78*f4a2713aSLionel Sambuc 79*f4a2713aSLionel Sambuc IsExact = DoubleBase->isObjCSelfExpr(); 80*f4a2713aSLionel Sambuc } 81*f4a2713aSLionel Sambuc break; 82*f4a2713aSLionel Sambuc } 83*f4a2713aSLionel Sambuc default: 84*f4a2713aSLionel Sambuc break; 85*f4a2713aSLionel Sambuc } 86*f4a2713aSLionel Sambuc 87*f4a2713aSLionel Sambuc return BaseInfoTy(D, IsExact); 88*f4a2713aSLionel Sambuc } 89*f4a2713aSLionel Sambuc 90*f4a2713aSLionel Sambuc 91*f4a2713aSLionel Sambuc FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy( 92*f4a2713aSLionel Sambuc const ObjCPropertyRefExpr *PropE) 93*f4a2713aSLionel Sambuc : Base(0, true), Property(getBestPropertyDecl(PropE)) { 94*f4a2713aSLionel Sambuc 95*f4a2713aSLionel Sambuc if (PropE->isObjectReceiver()) { 96*f4a2713aSLionel Sambuc const OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(PropE->getBase()); 97*f4a2713aSLionel Sambuc const Expr *E = OVE->getSourceExpr(); 98*f4a2713aSLionel Sambuc Base = getBaseInfo(E); 99*f4a2713aSLionel Sambuc } else if (PropE->isClassReceiver()) { 100*f4a2713aSLionel Sambuc Base.setPointer(PropE->getClassReceiver()); 101*f4a2713aSLionel Sambuc } else { 102*f4a2713aSLionel Sambuc assert(PropE->isSuperReceiver()); 103*f4a2713aSLionel Sambuc } 104*f4a2713aSLionel Sambuc } 105*f4a2713aSLionel Sambuc 106*f4a2713aSLionel Sambuc FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(const Expr *BaseE, 107*f4a2713aSLionel Sambuc const ObjCPropertyDecl *Prop) 108*f4a2713aSLionel Sambuc : Base(0, true), Property(Prop) { 109*f4a2713aSLionel Sambuc if (BaseE) 110*f4a2713aSLionel Sambuc Base = getBaseInfo(BaseE); 111*f4a2713aSLionel Sambuc // else, this is a message accessing a property on super. 112*f4a2713aSLionel Sambuc } 113*f4a2713aSLionel Sambuc 114*f4a2713aSLionel Sambuc FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy( 115*f4a2713aSLionel Sambuc const DeclRefExpr *DRE) 116*f4a2713aSLionel Sambuc : Base(0, true), Property(DRE->getDecl()) { 117*f4a2713aSLionel Sambuc assert(isa<VarDecl>(Property)); 118*f4a2713aSLionel Sambuc } 119*f4a2713aSLionel Sambuc 120*f4a2713aSLionel Sambuc FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy( 121*f4a2713aSLionel Sambuc const ObjCIvarRefExpr *IvarE) 122*f4a2713aSLionel Sambuc : Base(getBaseInfo(IvarE->getBase())), Property(IvarE->getDecl()) { 123*f4a2713aSLionel Sambuc } 124*f4a2713aSLionel Sambuc 125*f4a2713aSLionel Sambuc void FunctionScopeInfo::recordUseOfWeak(const ObjCMessageExpr *Msg, 126*f4a2713aSLionel Sambuc const ObjCPropertyDecl *Prop) { 127*f4a2713aSLionel Sambuc assert(Msg && Prop); 128*f4a2713aSLionel Sambuc WeakUseVector &Uses = 129*f4a2713aSLionel Sambuc WeakObjectUses[WeakObjectProfileTy(Msg->getInstanceReceiver(), Prop)]; 130*f4a2713aSLionel Sambuc Uses.push_back(WeakUseTy(Msg, Msg->getNumArgs() == 0)); 131*f4a2713aSLionel Sambuc } 132*f4a2713aSLionel Sambuc 133*f4a2713aSLionel Sambuc void FunctionScopeInfo::markSafeWeakUse(const Expr *E) { 134*f4a2713aSLionel Sambuc E = E->IgnoreParenCasts(); 135*f4a2713aSLionel Sambuc 136*f4a2713aSLionel Sambuc if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) { 137*f4a2713aSLionel Sambuc markSafeWeakUse(POE->getSyntacticForm()); 138*f4a2713aSLionel Sambuc return; 139*f4a2713aSLionel Sambuc } 140*f4a2713aSLionel Sambuc 141*f4a2713aSLionel Sambuc if (const ConditionalOperator *Cond = dyn_cast<ConditionalOperator>(E)) { 142*f4a2713aSLionel Sambuc markSafeWeakUse(Cond->getTrueExpr()); 143*f4a2713aSLionel Sambuc markSafeWeakUse(Cond->getFalseExpr()); 144*f4a2713aSLionel Sambuc return; 145*f4a2713aSLionel Sambuc } 146*f4a2713aSLionel Sambuc 147*f4a2713aSLionel Sambuc if (const BinaryConditionalOperator *Cond = 148*f4a2713aSLionel Sambuc dyn_cast<BinaryConditionalOperator>(E)) { 149*f4a2713aSLionel Sambuc markSafeWeakUse(Cond->getCommon()); 150*f4a2713aSLionel Sambuc markSafeWeakUse(Cond->getFalseExpr()); 151*f4a2713aSLionel Sambuc return; 152*f4a2713aSLionel Sambuc } 153*f4a2713aSLionel Sambuc 154*f4a2713aSLionel Sambuc // Has this weak object been seen before? 155*f4a2713aSLionel Sambuc FunctionScopeInfo::WeakObjectUseMap::iterator Uses; 156*f4a2713aSLionel Sambuc if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) 157*f4a2713aSLionel Sambuc Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr)); 158*f4a2713aSLionel Sambuc else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E)) 159*f4a2713aSLionel Sambuc Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE)); 160*f4a2713aSLionel Sambuc else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) 161*f4a2713aSLionel Sambuc Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE)); 162*f4a2713aSLionel Sambuc else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) { 163*f4a2713aSLionel Sambuc Uses = WeakObjectUses.end(); 164*f4a2713aSLionel Sambuc if (const ObjCMethodDecl *MD = MsgE->getMethodDecl()) { 165*f4a2713aSLionel Sambuc if (const ObjCPropertyDecl *Prop = MD->findPropertyDecl()) { 166*f4a2713aSLionel Sambuc Uses = 167*f4a2713aSLionel Sambuc WeakObjectUses.find(WeakObjectProfileTy(MsgE->getInstanceReceiver(), 168*f4a2713aSLionel Sambuc Prop)); 169*f4a2713aSLionel Sambuc } 170*f4a2713aSLionel Sambuc } 171*f4a2713aSLionel Sambuc } 172*f4a2713aSLionel Sambuc else 173*f4a2713aSLionel Sambuc return; 174*f4a2713aSLionel Sambuc 175*f4a2713aSLionel Sambuc if (Uses == WeakObjectUses.end()) 176*f4a2713aSLionel Sambuc return; 177*f4a2713aSLionel Sambuc 178*f4a2713aSLionel Sambuc // Has there been a read from the object using this Expr? 179*f4a2713aSLionel Sambuc FunctionScopeInfo::WeakUseVector::reverse_iterator ThisUse = 180*f4a2713aSLionel Sambuc std::find(Uses->second.rbegin(), Uses->second.rend(), WeakUseTy(E, true)); 181*f4a2713aSLionel Sambuc if (ThisUse == Uses->second.rend()) 182*f4a2713aSLionel Sambuc return; 183*f4a2713aSLionel Sambuc 184*f4a2713aSLionel Sambuc ThisUse->markSafe(); 185*f4a2713aSLionel Sambuc } 186*f4a2713aSLionel Sambuc 187*f4a2713aSLionel Sambuc void LambdaScopeInfo::getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E) { 188*f4a2713aSLionel Sambuc assert(Idx < getNumPotentialVariableCaptures() && 189*f4a2713aSLionel Sambuc "Index of potential capture must be within 0 to less than the " 190*f4a2713aSLionel Sambuc "number of captures!"); 191*f4a2713aSLionel Sambuc E = PotentiallyCapturingExprs[Idx]; 192*f4a2713aSLionel Sambuc if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) 193*f4a2713aSLionel Sambuc VD = dyn_cast<VarDecl>(DRE->getFoundDecl()); 194*f4a2713aSLionel Sambuc else if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) 195*f4a2713aSLionel Sambuc VD = dyn_cast<VarDecl>(ME->getMemberDecl()); 196*f4a2713aSLionel Sambuc else 197*f4a2713aSLionel Sambuc llvm_unreachable("Only DeclRefExprs or MemberExprs should be added for " 198*f4a2713aSLionel Sambuc "potential captures"); 199*f4a2713aSLionel Sambuc assert(VD); 200*f4a2713aSLionel Sambuc } 201*f4a2713aSLionel Sambuc 202*f4a2713aSLionel Sambuc FunctionScopeInfo::~FunctionScopeInfo() { } 203*f4a2713aSLionel Sambuc BlockScopeInfo::~BlockScopeInfo() { } 204*f4a2713aSLionel Sambuc LambdaScopeInfo::~LambdaScopeInfo() { } 205*f4a2713aSLionel Sambuc CapturedRegionScopeInfo::~CapturedRegionScopeInfo() { } 206