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