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