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