1243791Sdim//===--- ScopeInfo.cpp - Information about a semantic context -------------===// 2243791Sdim// 3243791Sdim// The LLVM Compiler Infrastructure 4243791Sdim// 5243791Sdim// This file is distributed under the University of Illinois Open Source 6243791Sdim// License. See LICENSE.TXT for details. 7243791Sdim// 8243791Sdim//===----------------------------------------------------------------------===// 9243791Sdim// 10243791Sdim// This file implements FunctionScopeInfo and its subclasses, which contain 11243791Sdim// information about a single function, block, lambda, or method body. 12243791Sdim// 13243791Sdim//===----------------------------------------------------------------------===// 14243791Sdim 15243791Sdim#include "clang/Sema/ScopeInfo.h" 16243791Sdim#include "clang/AST/Decl.h" 17243791Sdim#include "clang/AST/DeclObjC.h" 18243791Sdim#include "clang/AST/Expr.h" 19243791Sdim#include "clang/AST/ExprCXX.h" 20243791Sdim#include "clang/AST/ExprObjC.h" 21243791Sdim 22243791Sdimusing namespace clang; 23243791Sdimusing namespace sema; 24243791Sdim 25243791Sdimvoid FunctionScopeInfo::Clear() { 26243791Sdim HasBranchProtectedScope = false; 27243791Sdim HasBranchIntoScope = false; 28243791Sdim HasIndirectGoto = false; 29243791Sdim 30243791Sdim SwitchStack.clear(); 31243791Sdim Returns.clear(); 32243791Sdim ErrorTrap.reset(); 33243791Sdim PossiblyUnreachableDiags.clear(); 34243791Sdim WeakObjectUses.clear(); 35243791Sdim} 36243791Sdim 37243791Sdimstatic const NamedDecl *getBestPropertyDecl(const ObjCPropertyRefExpr *PropE) { 38243791Sdim if (PropE->isExplicitProperty()) 39243791Sdim return PropE->getExplicitProperty(); 40243791Sdim 41243791Sdim return PropE->getImplicitPropertyGetter(); 42243791Sdim} 43243791Sdim 44243791SdimFunctionScopeInfo::WeakObjectProfileTy::BaseInfoTy 45243791SdimFunctionScopeInfo::WeakObjectProfileTy::getBaseInfo(const Expr *E) { 46243791Sdim E = E->IgnoreParenCasts(); 47243791Sdim 48243791Sdim const NamedDecl *D = 0; 49243791Sdim bool IsExact = false; 50243791Sdim 51243791Sdim switch (E->getStmtClass()) { 52243791Sdim case Stmt::DeclRefExprClass: 53243791Sdim D = cast<DeclRefExpr>(E)->getDecl(); 54243791Sdim IsExact = isa<VarDecl>(D); 55243791Sdim break; 56243791Sdim case Stmt::MemberExprClass: { 57243791Sdim const MemberExpr *ME = cast<MemberExpr>(E); 58243791Sdim D = ME->getMemberDecl(); 59243791Sdim IsExact = isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()); 60243791Sdim break; 61243791Sdim } 62243791Sdim case Stmt::ObjCIvarRefExprClass: { 63243791Sdim const ObjCIvarRefExpr *IE = cast<ObjCIvarRefExpr>(E); 64243791Sdim D = IE->getDecl(); 65243791Sdim IsExact = IE->getBase()->isObjCSelfExpr(); 66243791Sdim break; 67243791Sdim } 68243791Sdim case Stmt::PseudoObjectExprClass: { 69243791Sdim const PseudoObjectExpr *POE = cast<PseudoObjectExpr>(E); 70243791Sdim const ObjCPropertyRefExpr *BaseProp = 71243791Sdim dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm()); 72243791Sdim if (BaseProp) { 73243791Sdim D = getBestPropertyDecl(BaseProp); 74243791Sdim 75243791Sdim const Expr *DoubleBase = BaseProp->getBase(); 76243791Sdim if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(DoubleBase)) 77243791Sdim DoubleBase = OVE->getSourceExpr(); 78243791Sdim 79243791Sdim IsExact = DoubleBase->isObjCSelfExpr(); 80243791Sdim } 81243791Sdim break; 82243791Sdim } 83243791Sdim default: 84243791Sdim break; 85243791Sdim } 86243791Sdim 87243791Sdim return BaseInfoTy(D, IsExact); 88243791Sdim} 89243791Sdim 90243791Sdim 91243791SdimFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy( 92243791Sdim const ObjCPropertyRefExpr *PropE) 93243791Sdim : Base(0, true), Property(getBestPropertyDecl(PropE)) { 94243791Sdim 95243791Sdim if (PropE->isObjectReceiver()) { 96243791Sdim const OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(PropE->getBase()); 97243791Sdim const Expr *E = OVE->getSourceExpr(); 98243791Sdim Base = getBaseInfo(E); 99243791Sdim } else if (PropE->isClassReceiver()) { 100243791Sdim Base.setPointer(PropE->getClassReceiver()); 101243791Sdim } else { 102243791Sdim assert(PropE->isSuperReceiver()); 103243791Sdim } 104243791Sdim} 105243791Sdim 106243791SdimFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(const Expr *BaseE, 107243791Sdim const ObjCPropertyDecl *Prop) 108243791Sdim : Base(0, true), Property(Prop) { 109243791Sdim if (BaseE) 110243791Sdim Base = getBaseInfo(BaseE); 111243791Sdim // else, this is a message accessing a property on super. 112243791Sdim} 113243791Sdim 114243791SdimFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy( 115243791Sdim const DeclRefExpr *DRE) 116243791Sdim : Base(0, true), Property(DRE->getDecl()) { 117243791Sdim assert(isa<VarDecl>(Property)); 118243791Sdim} 119243791Sdim 120243791SdimFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy( 121243791Sdim const ObjCIvarRefExpr *IvarE) 122243791Sdim : Base(getBaseInfo(IvarE->getBase())), Property(IvarE->getDecl()) { 123243791Sdim} 124243791Sdim 125243791Sdimvoid FunctionScopeInfo::recordUseOfWeak(const ObjCMessageExpr *Msg, 126243791Sdim const ObjCPropertyDecl *Prop) { 127243791Sdim assert(Msg && Prop); 128243791Sdim WeakUseVector &Uses = 129243791Sdim WeakObjectUses[WeakObjectProfileTy(Msg->getInstanceReceiver(), Prop)]; 130243791Sdim Uses.push_back(WeakUseTy(Msg, Msg->getNumArgs() == 0)); 131243791Sdim} 132243791Sdim 133243791Sdimvoid FunctionScopeInfo::markSafeWeakUse(const Expr *E) { 134243791Sdim E = E->IgnoreParenCasts(); 135243791Sdim 136243791Sdim if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) { 137243791Sdim markSafeWeakUse(POE->getSyntacticForm()); 138243791Sdim return; 139243791Sdim } 140243791Sdim 141243791Sdim if (const ConditionalOperator *Cond = dyn_cast<ConditionalOperator>(E)) { 142243791Sdim markSafeWeakUse(Cond->getTrueExpr()); 143243791Sdim markSafeWeakUse(Cond->getFalseExpr()); 144243791Sdim return; 145243791Sdim } 146243791Sdim 147243791Sdim if (const BinaryConditionalOperator *Cond = 148243791Sdim dyn_cast<BinaryConditionalOperator>(E)) { 149243791Sdim markSafeWeakUse(Cond->getCommon()); 150243791Sdim markSafeWeakUse(Cond->getFalseExpr()); 151243791Sdim return; 152243791Sdim } 153243791Sdim 154243791Sdim // Has this weak object been seen before? 155243791Sdim FunctionScopeInfo::WeakObjectUseMap::iterator Uses; 156243791Sdim if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) 157243791Sdim Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr)); 158243791Sdim else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E)) 159243791Sdim Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE)); 160243791Sdim else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) 161243791Sdim Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE)); 162243791Sdim else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) { 163243791Sdim Uses = WeakObjectUses.end(); 164243791Sdim if (const ObjCMethodDecl *MD = MsgE->getMethodDecl()) { 165243791Sdim if (const ObjCPropertyDecl *Prop = MD->findPropertyDecl()) { 166243791Sdim Uses = 167243791Sdim WeakObjectUses.find(WeakObjectProfileTy(MsgE->getInstanceReceiver(), 168243791Sdim Prop)); 169243791Sdim } 170243791Sdim } 171243791Sdim } 172243791Sdim else 173243791Sdim return; 174243791Sdim 175243791Sdim if (Uses == WeakObjectUses.end()) 176243791Sdim return; 177243791Sdim 178243791Sdim // Has there been a read from the object using this Expr? 179243791Sdim FunctionScopeInfo::WeakUseVector::reverse_iterator ThisUse = 180243791Sdim std::find(Uses->second.rbegin(), Uses->second.rend(), WeakUseTy(E, true)); 181243791Sdim if (ThisUse == Uses->second.rend()) 182243791Sdim return; 183243791Sdim 184243791Sdim ThisUse->markSafe(); 185243791Sdim} 186243791Sdim 187263508Sdimvoid LambdaScopeInfo::getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E) { 188263508Sdim assert(Idx < getNumPotentialVariableCaptures() && 189263508Sdim "Index of potential capture must be within 0 to less than the " 190263508Sdim "number of captures!"); 191263508Sdim E = PotentiallyCapturingExprs[Idx]; 192263508Sdim if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) 193263508Sdim VD = dyn_cast<VarDecl>(DRE->getFoundDecl()); 194263508Sdim else if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) 195263508Sdim VD = dyn_cast<VarDecl>(ME->getMemberDecl()); 196263508Sdim else 197263508Sdim llvm_unreachable("Only DeclRefExprs or MemberExprs should be added for " 198263508Sdim "potential captures"); 199263508Sdim assert(VD); 200263508Sdim} 201263508Sdim 202243791SdimFunctionScopeInfo::~FunctionScopeInfo() { } 203243791SdimBlockScopeInfo::~BlockScopeInfo() { } 204243791SdimLambdaScopeInfo::~LambdaScopeInfo() { } 205251662SdimCapturedRegionScopeInfo::~CapturedRegionScopeInfo() { } 206