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